DBIx-RunSQL-0.15/0000755000175000017500000000000012731510604012712 5ustar corioncorionDBIx-RunSQL-0.15/META.json0000644000175000017500000000233212731510604014333 0ustar corioncorion{ "abstract" : "run SQL from a file", "author" : [ "Max Maischein " ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.150005", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "DBIx-RunSQL", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "DBI" : "0", "perl" : "5.006" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "http://rt.cpan.org/Public/Dist/Display.html?Name=DBIx-RunSQL" }, "license" : [ "http://dev.perl.org/licenses/" ], "repository" : { "url" : "http://github.com/Corion/dbix--runsql" } }, "version" : "0.15", "x_serialization_backend" : "JSON::PP version 2.27202" } DBIx-RunSQL-0.15/Changes0000644000175000017500000000414212731510600014202 0ustar corioncorion0.15 20160619 . Fix grammar error (RT #114768, contributed by eythian ) + Allow for trailing whitespace while parsing SQL (RT #115442, contributed by niceperl) 0.14 20160524 + ->handle_command_line now also accepts an SQL string instead of only accepting SQL files . Silence some warnings if a statement does not return columns (like a CREATE statement). RT #114647 0.13 20150519 + Fix bad thinko error in ->run_sql that prevented any results from being shown 0.12 20140222 + If Text::Table is installed, output SELECT statements through it instead of simply using \t . Document more of the internal helper routines 0.11 20131120 + Add functionality for SELECT statements 0.10 20130510 . Fix the MANIFEST which listed MYMETA.* . Fix a bug where ->handle_command_line() never properly processed the parameters given to it. 0.09 20120611 + Parse triggers. This fixes RT #77378 Test and report by Gabor Szabo 0.08 20120518 . Add a test for warnings raised while executing SQL (contributed by David Golden) + Respect the 'verbose' setting, fixes RT #77260 (contributed by David Golden) 0.07 20111023 . Fix bad test skip count . Documentation fixes o no need to upgrade 0.06 20110920 Suggested by Gabor Szabo + allow a different output handle for the verbose messages + Allow a callback for the verbose messages + Separate the SQL statements by "--" in the verbose output ! SQL errors are now fatal + Add --force option to ignore SQL errors (fixes RT #70998) 0.05 20110127 . Fix synopsis to use :dbname instead of (wrong) :dbfile parameter for DBD::SQLite . Added link to github repo . Added metainformation about bugtracker etc. . Bumped copyright 0.04 20101111 . Actually document ->handle_command_line, thanks to Terrence Brannon . Add author information, license information 0.03 20100518 . ->create now returns the database handle so you can use it to create :memory: databases in SQLite 0.02 20100213 . Collected from various copies and released DBIx-RunSQL-0.15/META.yml0000644000175000017500000000133512731510603014164 0ustar corioncorion--- abstract: 'run SQL from a file' author: - 'Max Maischein ' build_requires: ExtUtils::MakeMaker: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.150005' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: DBIx-RunSQL no_index: directory: - t - inc requires: DBI: '0' perl: '5.006' resources: bugtracker: http://rt.cpan.org/Public/Dist/Display.html?Name=DBIx-RunSQL license: http://dev.perl.org/licenses/ repository: http://github.com/Corion/dbix--runsql version: '0.15' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' DBIx-RunSQL-0.15/MANIFEST.SKIP0000644000175000017500000000022212731510524014605 0ustar corioncorion.cvsignore$ ^.git/ ^.lwpcookies ^.releaserc ^blib/ ^DBIx-RunSQL-.* CVS/ ^pm_to_blib .tar.gz$ .old$ ^Makefile$ ^cvstest$ ^blibdirs$ .bak$ ^MYMETA.*DBIx-RunSQL-0.15/.gitignore0000644000175000017500000000012312731510532014676 0ustar corioncoriondb/ Makefile blib/ pm_to_blib MANIFEST.bak DBIx-RunSQL-* MYMETA.* .releasercDBIx-RunSQL-0.15/README.mkdn0000644000175000017500000002234212731510600014521 0ustar corioncorion# NAME DBIx::RunSQL - run SQL from a file # SYNOPSIS #!/usr/bin/perl -w use strict; use lib 'lib'; use DBIx::RunSQL; my $test_dbh = DBIx::RunSQL->create( dsn => 'dbi:SQLite:dbname=:memory:', sql => 'sql/create.sql', force => 1, verbose => 1, ); ... # run your tests with a DB setup fresh from setup.sql # METHODS ## `DBIx::RunSQL->create ARGS` ## `DBIx::RunSQL->run ARGS` Runs the SQL commands and returns the database handle. In list context, it returns the database handle and the suggested exit code. - `sql` - name of the file containing the SQL statements The default is `sql/create.sql` If `sql` is a reference to a glob or a filehandle, the SQL will be read from that. **not implemented** If `sql` is undefined, the `$::DATA` or the `0` filehandle will be read until exhaustion. **not implemented** This allows one to create SQL-as-programs as follows: #!/usr/bin/perl -w -MDBIx::RunSQL -e 'create()' create table ... If you want to run SQL statements from a scalar, you can simply pass in a reference to a scalar containing the SQL: sql => \"update mytable set foo='bar';", - `dsn`, `user`, `password` - DBI parameters for connecting to the DB - `dbh` - a premade database handle to be used instead of `dsn` - `force` - continue even if errors are encountered - `verbose` - print each SQL statement as it is run - `verbose_handler` - callback to call with each SQL statement instead of `print` - `verbose_fh` - filehandle to write to instead of `STDOUT` ## `DBIx::RunSQL->run_sql_file ARGS` my $dbh = DBI->connect(...) for my $file (sort glob '*.sql') { DBIx::RunSQL->run_sql_file( verbose => 1, dbh => $dbh, sql => $file, ); }; Runs an SQL file on a prepared database handle. Returns the number of errors encountered. If the statement returns rows, these are printed separated with tabs. - `dbh` - a premade database handle - `sql` - name of the file containing the SQL statements - `force` - continue even if errors are encountered - `verbose` - print each SQL statement as it is run - `verbose_handler` - callback to call with each SQL statement instead of `print` - `verbose_fh` - filehandle to write to instead of `STDOUT` - `output_bool` - whether to exit with a nonzero exit code if any row is found This makes the function return a nonzero value even if there is no error but a row was found. - `output_string` - whether to output the (one) row and column, without any headers ## `DBIx::RunSQL->run_sql ARGS` my $dbh = DBI->connect(...) for my $file (sort glob '*.sql') { DBIx::RunSQL->run_sql_file( verbose => 1, dbh => $dbh, sql => 'create table foo', ); }; Runs an SQL string on a prepared database handle. Returns the number of errors encountered. If the statement returns rows, these are printed separated with tabs, but see the `output_bool` and `output_string` options. - `dbh` - a premade database handle - `sql` - string or array reference containing the SQL statements - `force` - continue even if errors are encountered - `verbose` - print each SQL statement as it is run - `verbose_handler` - callback to call with each SQL statement instead of `print` - `verbose_fh` - filehandle to write to instead of `STDOUT` - `output_bool` - whether to exit with a nonzero exit code if any row is found This makes the function return a nonzero value even if there is no error but a row was found. - `output_string` - whether to output the (one) row and column, without any headers ## `DBIx::RunSQL->format_results %options` my $sth= $dbh->prepare( 'select * from foo' ); $sth->execute(); print DBIx::RunSQL->format_results( sth => $sth ); Executes `$sth->fetchall_arrayref` and returns the results either as tab separated string or formatted using [Text::Table](https://metacpan.org/pod/Text::Table) if the module is available. If you find yourself using this often to create reports, you may really want to look at [Querylet](https://metacpan.org/pod/Querylet) instead. - `sth` - the executed statement handle - `formatter` - if you want to force `tab` or `Text::Table` usage, you can do it through that parameter. In fact, the module will use anything other than `tab` as the class name and assume that the interface is compatible to `Text::Table`. Note that the query results are returned as one large string, so you really do not want to run this for large(r) result sets. ## `DBIx::RunSQL->split_sql ARGS` my @statements= DBIx::RunSQL->split_sql( <<'SQL'); create table foo (name varchar(64)); create trigger foo_insert on foo before insert; new.name= 'foo-'||old.name; end; insert into foo name values ('bar'); SQL # Returns three elements This is a helper subroutine to split a sequence of (semicolon-newline-delimited) SQL statements into separate statements. It is documented because it is not a very smart subroutine and you might want to override or replace it. It might also be useful outside the context of [DBIx::RunSQL](https://metacpan.org/pod/DBIx::RunSQL) if you need to split up a large blob of SQL statements into smaller pieces. The subroutine needs the whole sequence of SQL statements in memory. If you are attempting to restore a large SQL dump backup into your database, this approach might not be suitable. # PROGRAMMER USAGE This module abstracts away the "run these SQL statements to set up your database" into a module. In some situations you want to give the setup SQL to a database admin, but in other situations, for example testing, you want to run the SQL statements against an in-memory database. This module abstracts away the reading of SQL from a file and allows for various command line parameters to be passed in. A skeleton `create-db.sql` looks like this: #!/usr/bin/perl -w use strict; use lib 'lib'; use DBIx::RunSQL; my $exitcode = DBIx::RunSQL->handle_command_line('myapp'); exit $exitcode; =head1 NAME create-db.pl - Create the database =head1 ABSTRACT This sets up the database. The following options are recognized: =over 4 =item C<--user> USERNAME =item C<--password> PASSWORD =item C<--dsn> DSN The DBI DSN to use for connecting to the database =item C<--sql> SQLFILE The alternative SQL file to use instead of C. =item C<--force> Don't stop on errors =item C<--help> Show this message. =cut ## `DBIx::RunSQL->handle_command_line` Parses the command line. This is a convenience method, which passes the following command line arguments to `->create`: --user --password --dsn --sql --force --verbose In addition, it handles the following switches through [Pod::Usage](https://metacpan.org/pod/Pod::Usage): --help --man See also the section PROGRAMMER USAGE for a sample program to set up a database from an SQL file. # NOTES ## COMMENT FILTERING The module tries to keep the SQL as much verbatim as possible. It filters all lines that end in semicolons but contain only SQL comments. All other comments are passed through to the database with the next statement. ## TRIGGER HANDLING This module uses a very simplicistic approach to recognize triggers. Triggers are problematic because they consist of multiple SQL statements and this module does not implement a full SQL parser. An trigger is recognized by the following sequence of lines CREATE TRIGGER ... END; If your SQL dialect uses a different syntax, it might still work to put the whole trigger on a single line in the input file. ## OTHER APPROACHES If you find yourself wanting to write SELECT statements, consider looking at [Querylet](https://metacpan.org/pod/Querylet) instead, which is geared towards that and even has an interface for Excel or HTML output. If you find yourself wanting to write parametrized queries as `.sql` files, consider looking at [Data::Phrasebook::SQL](https://metacpan.org/pod/Data::Phrasebook::SQL) or potentially [DBIx::SQLHandler](https://metacpan.org/pod/DBIx::SQLHandler). # SEE ALSO [ORLite::Migrate](https://metacpan.org/pod/ORLite::Migrate) # REPOSITORY The public repository of this module is [http://github.com/Corion/DBIx--RunSQL](http://github.com/Corion/DBIx--RunSQL). # SUPPORT The public support forum of this module is [http://perlmonks.org/](http://perlmonks.org/). # BUG TRACKER Please report bugs in this module via the RT CPAN bug queue at [https://rt.cpan.org/Public/Dist/Display.html?Name=DBIx-RunSQL](https://rt.cpan.org/Public/Dist/Display.html?Name=DBIx-RunSQL) or via mail to [bug-dbix-runsql@rt.cpan.org](https://metacpan.org/pod/bug-dbix-runsql@rt.cpan.org). # AUTHOR Max Maischein `corion@cpan.org` # COPYRIGHT (c) Copyright 2009-2016 by Max Maischein `corion@cpan.org`. # LICENSE This module is released under the same terms as Perl itself. DBIx-RunSQL-0.15/README0000644000175000017500000002263412731510600013575 0ustar corioncorionNAME DBIx::RunSQL - run SQL from a file SYNOPSIS #!/usr/bin/perl -w use strict; use lib 'lib'; use DBIx::RunSQL; my $test_dbh = DBIx::RunSQL->create( dsn => 'dbi:SQLite:dbname=:memory:', sql => 'sql/create.sql', force => 1, verbose => 1, ); ... # run your tests with a DB setup fresh from setup.sql METHODS DBIx::RunSQL->create ARGS DBIx::RunSQL->run ARGS Runs the SQL commands and returns the database handle. In list context, it returns the database handle and the suggested exit code. * sql - name of the file containing the SQL statements The default is sql/create.sql If sql is a reference to a glob or a filehandle, the SQL will be read from that. not implemented If sql is undefined, the $::DATA or the 0 filehandle will be read until exhaustion. not implemented This allows one to create SQL-as-programs as follows: #!/usr/bin/perl -w -MDBIx::RunSQL -e 'create()' create table ... If you want to run SQL statements from a scalar, you can simply pass in a reference to a scalar containing the SQL: sql => \"update mytable set foo='bar';", * dsn, user, password - DBI parameters for connecting to the DB * dbh - a premade database handle to be used instead of dsn * force - continue even if errors are encountered * verbose - print each SQL statement as it is run * verbose_handler - callback to call with each SQL statement instead of print * verbose_fh - filehandle to write to instead of STDOUT DBIx::RunSQL->run_sql_file ARGS my $dbh = DBI->connect(...) for my $file (sort glob '*.sql') { DBIx::RunSQL->run_sql_file( verbose => 1, dbh => $dbh, sql => $file, ); }; Runs an SQL file on a prepared database handle. Returns the number of errors encountered. If the statement returns rows, these are printed separated with tabs. * dbh - a premade database handle * sql - name of the file containing the SQL statements * force - continue even if errors are encountered * verbose - print each SQL statement as it is run * verbose_handler - callback to call with each SQL statement instead of print * verbose_fh - filehandle to write to instead of STDOUT * output_bool - whether to exit with a nonzero exit code if any row is found This makes the function return a nonzero value even if there is no error but a row was found. * output_string - whether to output the (one) row and column, without any headers DBIx::RunSQL->run_sql ARGS my $dbh = DBI->connect(...) for my $file (sort glob '*.sql') { DBIx::RunSQL->run_sql_file( verbose => 1, dbh => $dbh, sql => 'create table foo', ); }; Runs an SQL string on a prepared database handle. Returns the number of errors encountered. If the statement returns rows, these are printed separated with tabs, but see the output_bool and output_string options. * dbh - a premade database handle * sql - string or array reference containing the SQL statements * force - continue even if errors are encountered * verbose - print each SQL statement as it is run * verbose_handler - callback to call with each SQL statement instead of print * verbose_fh - filehandle to write to instead of STDOUT * output_bool - whether to exit with a nonzero exit code if any row is found This makes the function return a nonzero value even if there is no error but a row was found. * output_string - whether to output the (one) row and column, without any headers DBIx::RunSQL->format_results %options my $sth= $dbh->prepare( 'select * from foo' ); $sth->execute(); print DBIx::RunSQL->format_results( sth => $sth ); Executes $sth->fetchall_arrayref and returns the results either as tab separated string or formatted using Text::Table if the module is available. If you find yourself using this often to create reports, you may really want to look at Querylet instead. * sth - the executed statement handle * formatter - if you want to force tab or Text::Table usage, you can do it through that parameter. In fact, the module will use anything other than tab as the class name and assume that the interface is compatible to Text::Table. Note that the query results are returned as one large string, so you really do not want to run this for large(r) result sets. DBIx::RunSQL->split_sql ARGS my @statements= DBIx::RunSQL->split_sql( <<'SQL'); create table foo (name varchar(64)); create trigger foo_insert on foo before insert; new.name= 'foo-'||old.name; end; insert into foo name values ('bar'); SQL # Returns three elements This is a helper subroutine to split a sequence of (semicolon-newline-delimited) SQL statements into separate statements. It is documented because it is not a very smart subroutine and you might want to override or replace it. It might also be useful outside the context of DBIx::RunSQL if you need to split up a large blob of SQL statements into smaller pieces. The subroutine needs the whole sequence of SQL statements in memory. If you are attempting to restore a large SQL dump backup into your database, this approach might not be suitable. PROGRAMMER USAGE This module abstracts away the "run these SQL statements to set up your database" into a module. In some situations you want to give the setup SQL to a database admin, but in other situations, for example testing, you want to run the SQL statements against an in-memory database. This module abstracts away the reading of SQL from a file and allows for various command line parameters to be passed in. A skeleton create-db.sql looks like this: #!/usr/bin/perl -w use strict; use lib 'lib'; use DBIx::RunSQL; my $exitcode = DBIx::RunSQL->handle_command_line('myapp'); exit $exitcode; =head1 NAME create-db.pl - Create the database =head1 ABSTRACT This sets up the database. The following options are recognized: =over 4 =item C<--user> USERNAME =item C<--password> PASSWORD =item C<--dsn> DSN The DBI DSN to use for connecting to the database =item C<--sql> SQLFILE The alternative SQL file to use instead of C. =item C<--force> Don't stop on errors =item C<--help> Show this message. =cut DBIx::RunSQL->handle_command_line Parses the command line. This is a convenience method, which passes the following command line arguments to ->create: --user --password --dsn --sql --force --verbose In addition, it handles the following switches through Pod::Usage: --help --man See also the section PROGRAMMER USAGE for a sample program to set up a database from an SQL file. NOTES COMMENT FILTERING The module tries to keep the SQL as much verbatim as possible. It filters all lines that end in semicolons but contain only SQL comments. All other comments are passed through to the database with the next statement. TRIGGER HANDLING This module uses a very simplicistic approach to recognize triggers. Triggers are problematic because they consist of multiple SQL statements and this module does not implement a full SQL parser. An trigger is recognized by the following sequence of lines CREATE TRIGGER ... END; If your SQL dialect uses a different syntax, it might still work to put the whole trigger on a single line in the input file. OTHER APPROACHES If you find yourself wanting to write SELECT statements, consider looking at Querylet instead, which is geared towards that and even has an interface for Excel or HTML output. If you find yourself wanting to write parametrized queries as .sql files, consider looking at Data::Phrasebook::SQL or potentially DBIx::SQLHandler. SEE ALSO ORLite::Migrate REPOSITORY The public repository of this module is http://github.com/Corion/DBIx--RunSQL. SUPPORT The public support forum of this module is http://perlmonks.org/. BUG TRACKER Please report bugs in this module via the RT CPAN bug queue at https://rt.cpan.org/Public/Dist/Display.html?Name=DBIx-RunSQL or via mail to bug-dbix-runsql@rt.cpan.org. AUTHOR Max Maischein corion@cpan.org COPYRIGHT (c) Copyright 2009-2016 by Max Maischein corion@cpan.org. LICENSE This module is released under the same terms as Perl itself. DBIx-RunSQL-0.15/t/0000755000175000017500000000000012731510603013154 5ustar corioncorionDBIx-RunSQL-0.15/t/01-force.t0000644000175000017500000000155312731510532014662 0ustar corioncorion#!perl -w use strict; use Test::More; use DBIx::RunSQL; my $can_run = eval { require DBD::SQLite; 1 }; if (not $can_run) { plan skip_all => "SQLite not installed"; } plan tests => 5; my $warn; local $SIG{__WARN__} = sub { $warn = shift }; my $lives = eval { my $test_dbh = DBIx::RunSQL->create( dsn => 'dbi:SQLite:dbname=:memory:', sql => $0, ); 1; }; my $err = $@; ok !$lives, "We die on invalid SQL"; isn't $@, '', "We die with some error message"; $lives = eval { my $test_dbh = DBIx::RunSQL->create( dsn => 'dbi:SQLite:dbname=:memory:', sql => $0, force => 1, ); 1; }; $err = $@; ok $lives, "We can force invalid SQL"; is $@, '', "We don't die with some error message"; like $warn, qr/SQL ERROR/, "We still warn about SQL errors"; DBIx-RunSQL-0.15/t/rt115442.t0000644000175000017500000000052012731510600014441 0ustar corioncorion#!perl -w use strict; use Test::More; use Data::Dumper; use DBIx::RunSQL; plan tests => 1; my @statements = DBIx::RunSQL->split_sql(<<'SQL'); DROP TABLE IF EXISTS player1; DROP TABLE IF EXISTS player2; SQL is scalar( @statements ), 2, "Trailing whitespace is allowed in statements" or diag Dumper \@statements; DBIx-RunSQL-0.15/t/02-trigger.t0000644000175000017500000000074012731510532015225 0ustar corioncorion#!perl -w use strict; use Test::More; use DBIx::RunSQL; my $can_run = eval { require DBD::SQLite; 1 }; if (not $can_run) { plan skip_all => "SQLite not installed"; } plan tests => 1; my $lives = eval { my $test_dbh = DBIx::RunSQL->create( dsn => 'dbi:SQLite:dbname=:memory:', sql => 't/trigger.sql', #verbose => 1, ); 1; }; my $err = $@; ok $lives, "We can parse triggers" or diag $err; DBIx-RunSQL-0.15/t/rt77378.sql0000644000175000017500000000053212731510532014743 0ustar corioncorionCREATE TABLE user ( id INTEGER PRIMARY KEY, name VARCHAR(255) ); CREATE TABLE emails ( uid INTEGER NOT NULL, name VARCHAR(255) UNIQUE NOT NULL, FOREIGN KEY (uid) REFERENCES user(id) ); CREATE TRIGGER user_cleanup BEFORE DELETE ON user FOR EACH ROW BEGIN DELETE FROM email WHERE uid=OLD.id; END;DBIx-RunSQL-0.15/t/trigger.sql0000644000175000017500000000077312731510532015350 0ustar corioncorion-- This commented-out statement will not get passed through; -- SECRET PRAGMA #foo will get passed through with the next statement create table test ( id integer unique not null, descr text default '', ts text ); CREATE TRIGGER trg_test_1 AFTER INSERT ON test BEGIN UPDATE test SET ts = DATETIME('NOW') WHERE rowid = new.rowid; END; CREATE TRIGGER trg_test_2 AFTER INSERT ON test BEGIN UPDATE test SET ts = DATETIME('NOW') WHERE rowid = new.rowid; END; DBIx-RunSQL-0.15/t/05-output-bool.t0000644000175000017500000000145012731510532016055 0ustar corioncorion#!perl -w use strict; use Test::More; use DBIx::RunSQL; use Data::Dumper; # Test against a "real" database if we have one: if( ! eval { require DBD::SQLite; 1 }) { plan skip_all => $@; exit; }; plan tests => 1; # Redirect STDOUT to a variable close STDOUT; # sssh open STDOUT, '>', \my $output; my $exitcode = DBIx::RunSQL->handle_command_line( "my-test-app", '--bool', '--dsn' => 'dbi:SQLite:dbname=:memory:', '--sql' => <<'SQL', create table foo (bar integer, baz varchar); insert into foo (bar,baz) values (1,'hello'); insert into foo (bar,baz) values (2,'world'); select * from foo; SQL ); is $exitcode, 1, "We get a nonzero exit code if a row gets selected with --bool" or diag $output; done_testing();DBIx-RunSQL-0.15/t/05-select.t0000644000175000017500000000254412731510532015050 0ustar corioncorion#!perl -w use strict; use Test::More; use DBIx::RunSQL; my $can_run = eval { require DBD::SQLite; 1 }; if (not $can_run) { plan skip_all => "SQLite not installed"; } plan tests => 6; my $sql= <<'SQL'; create table foo ( name varchar(64) , age decimal(4) ); insert into foo (name,age) values ('bar',100); insert into foo (name,age) values ('baz',1); insert into foo (name,age) values ('Some loong string',1000); SQL my $test_dbh = DBIx::RunSQL->create( dsn => 'dbi:SQLite:dbname=:memory:', sql => \$sql, ); my $sth= $test_dbh->prepare(<<'SQL'); select * from foo; SQL $sth->execute; my $result= DBIx::RunSQL->format_results( sth => $sth ); isn't $result, undef, "We got some kind of result"; like $result, qr/\bname\b.*?\bage\b/m, "Things that look like 'name' and 'age' appear in the string"; like $result, qr/\bbar\b.*?\b100\b/m, "Things that look like 'bar' and '100' appear in the string"; $sth= $test_dbh->prepare(<<'SQL'); select * from foo where 1=0; SQL $sth->execute; $result= DBIx::RunSQL->format_results( sth => $sth ); isn't $result, undef, "We got some kind of result"; like $result, qr/\bname\b.*?\bage\b/m, "An empty resultset still outputs the column titles"; unlike $result, qr/\bbar\b.*?\b100\b/m, "(but obviously, no values)"; DBIx-RunSQL-0.15/t/04-handle-parameters.t0000644000175000017500000000112412731510532017155 0ustar corioncorion#!perl -w use strict; use Test::More tests => 2; use DBIx::RunSQL; use Data::Dumper; my @received; { no warnings 'redefine'; sub DBIx::RunSQL::create { @received= @_; }; }; DBIx::RunSQL->handle_command_line( "my-test-app", ); my ($package,%options)= @received; is $options{ dsn }, "dbi:SQLite:dbname=db/my-test-app.sqlite", "DSN gets appname used as default"; DBIx::RunSQL->handle_command_line( "my-test-app", '--dsn' => 'dbi:Magic:', ); ($package,%options)= @received; is $options{ dsn }, "dbi:Magic:", "DSN gets passed through"; DBIx-RunSQL-0.15/t/03-comment.t0000644000175000017500000000114712731510532015227 0ustar corioncorion#!perl -w use strict; use Test::More; use DBIx::RunSQL; my $can_run = eval { require DBD::SQLite; 1 }; if (not $can_run) { plan skip_all => "SQLite not installed"; } plan tests => 2; my @statements; my $test_dbh = DBIx::RunSQL->create( dsn => 'dbi:SQLite:dbname=:memory:', sql => 't/trigger.sql', verbose_handler => sub { push @statements, $_[0] }, verbose => 1, ); unlike $statements[0], qr/commented-out/, "Commented out things that look like statements get filtered"; like $statements[0], qr/-- SECRET PRAGMA #foo/, "Comments survive parsing"; DBIx-RunSQL-0.15/t/00-use.t0000644000175000017500000000011412731510532014347 0ustar corioncorion#!perl -w use strict; use Test::More tests => 1; use_ok 'DBIx::RunSQL';DBIx-RunSQL-0.15/t/rt77378.t0000644000175000017500000000072712731510532014415 0ustar corioncorion#!perl -w use strict; use Test::More; use DBIx::RunSQL; my $can_run = eval { require DBD::SQLite; 1 }; if (not $can_run) { plan skip_all => "SQLite not installed"; } plan tests => 1; my $dsn = 'dbi:SQLite:dbname=:memory:'; my $lives = eval { DBIx::RunSQL->create( verbose => 0, dsn => $dsn, sql => 't/rt77378.sql', ); 1 }; ok $lives, "We can parse triggers (RT 77378)" or diag $@;DBIx-RunSQL-0.15/lib/0000755000175000017500000000000012731510603013457 5ustar corioncorionDBIx-RunSQL-0.15/lib/DBIx/0000755000175000017500000000000012731510603014245 5ustar corioncorionDBIx-RunSQL-0.15/lib/DBIx/RunSQL.pm0000644000175000017500000003570712731510600015740 0ustar corioncorionpackage DBIx::RunSQL; use strict; use DBI; use vars qw($VERSION); $VERSION = '0.15'; =head1 NAME DBIx::RunSQL - run SQL from a file =cut =head1 SYNOPSIS #!/usr/bin/perl -w use strict; use lib 'lib'; use DBIx::RunSQL; my $test_dbh = DBIx::RunSQL->create( dsn => 'dbi:SQLite:dbname=:memory:', sql => 'sql/create.sql', force => 1, verbose => 1, ); ... # run your tests with a DB setup fresh from setup.sql =head1 METHODS =head2 C<< DBIx::RunSQL->create ARGS >> =head2 C<< DBIx::RunSQL->run ARGS >> Runs the SQL commands and returns the database handle. In list context, it returns the database handle and the suggested exit code. =over 4 =item * C - name of the file containing the SQL statements The default is C If C is a reference to a glob or a filehandle, the SQL will be read from that. B If C is undefined, the C<$::DATA> or the C<0> filehandle will be read until exhaustion. B This allows one to create SQL-as-programs as follows: #!/usr/bin/perl -w -MDBIx::RunSQL -e 'create()' create table ... If you want to run SQL statements from a scalar, you can simply pass in a reference to a scalar containing the SQL: sql => \"update mytable set foo='bar';", =item * C, C, C - DBI parameters for connecting to the DB =item * C - a premade database handle to be used instead of C =item * C - continue even if errors are encountered =item * C - print each SQL statement as it is run =item * C - callback to call with each SQL statement instead of C =item * C - filehandle to write to instead of C =back =cut sub create { my ($self,%args) = @_; $args{sql} ||= 'sql/create.sql'; my $dbh = delete $args{ dbh }; if (! $dbh) { $dbh = DBI->connect($args{dsn}, $args{user}, $args{password}, {}) or die "Couldn't connect to DSN '$args{dsn}' : " . DBI->errstr; }; my $errors = $self->run_sql_file( dbh => $dbh, %args, ); return wantarray ? ($dbh, $errors) : $dbh; }; *run = *run = \&create; =head2 C<< DBIx::RunSQL->run_sql_file ARGS >> my $dbh = DBI->connect(...) for my $file (sort glob '*.sql') { DBIx::RunSQL->run_sql_file( verbose => 1, dbh => $dbh, sql => $file, ); }; Runs an SQL file on a prepared database handle. Returns the number of errors encountered. If the statement returns rows, these are printed separated with tabs. =over 4 =item * C - a premade database handle =item * C - name of the file containing the SQL statements =item * C - continue even if errors are encountered =item * C - print each SQL statement as it is run =item * C - callback to call with each SQL statement instead of C =item * C - filehandle to write to instead of C =item * C - whether to exit with a nonzero exit code if any row is found This makes the function return a nonzero value even if there is no error but a row was found. =item * C - whether to output the (one) row and column, without any headers =back =cut sub run_sql_file { my ($self,%args) = @_; my @sql; { open my $fh, "<", $args{sql} or die "Couldn't read '$args{sql}' : $!"; # potentially this should become C<< $/ = ";\n"; >> # and a while loop to handle large SQL files local $/; $args{ sql }= <$fh>; # sluuurp }; $self->run_sql( %args ); } =head2 C<< DBIx::RunSQL->run_sql ARGS >> my $dbh = DBI->connect(...) for my $file (sort glob '*.sql') { DBIx::RunSQL->run_sql_file( verbose => 1, dbh => $dbh, sql => 'create table foo', ); }; Runs an SQL string on a prepared database handle. Returns the number of errors encountered. If the statement returns rows, these are printed separated with tabs, but see the C and C options. =over 4 =item * C - a premade database handle =item * C - string or array reference containing the SQL statements =item * C - continue even if errors are encountered =item * C - print each SQL statement as it is run =item * C - callback to call with each SQL statement instead of C =item * C - filehandle to write to instead of C =item * C - whether to exit with a nonzero exit code if any row is found This makes the function return a nonzero value even if there is no error but a row was found. =item * C - whether to output the (one) row and column, without any headers =back =cut sub run_sql { my ($self,%args) = @_; my $errors = 0; my @sql= 'ARRAY' eq ref $args{ sql } ? @{ $args{ sql }} : $args{ sql }; $args{ verbose_handler } ||= sub { $args{ verbose_fh } ||= \*main::STDOUT; print { $args{ verbose_fh } } "$_[0]\n"; }; my $status = delete $args{ verbose_handler }; # Because we blindly split above on /;\n/ # we need to reconstruct multi-line CREATE TRIGGER statements here again my $trigger; for my $statement ($self->split_sql( $args{ sql })) { # skip "statements" that consist only of comments next unless $statement =~ /^\s*[A-Z][A-Z]/mi; $status->($statement) if $args{verbose}; my $sth = $args{dbh}->prepare($statement); if(! $sth) { if (!$args{force}) { die "[SQL ERROR]: $statement\n"; } else { warn "[SQL ERROR]: $statement\n"; }; } else { my $status= $sth->execute(); if(! $status) { if (!$args{force}) { die "[SQL ERROR]: $statement\n"; } else { warn "[SQL ERROR]: $statement\n"; }; } elsif( defined $sth->{NUM_OF_FIELDS} and 0 < $sth->{NUM_OF_FIELDS} ) { # SELECT statement, output results if( $args{ output_bool }) { my $res = $self->format_results( sth => $sth, no_header_when_empty => 1, %args ); print $res; $errors = length $res > 0; } elsif( $args{ output_string }) { local $self->{formatter} = 'tab'; print $self->format_results( sth => $sth, headers => 0, %args ); } else { print $self->format_results( sth => $sth, %args ); }; }; }; }; $errors } sub parse_command_line { my ($package,$appname,@argv) = @_; require Getopt::Long; Getopt::Long->import(); require Pod::Usage; Pod::Usage->import(); if (! @argv) { @argv = @ARGV }; local @ARGV = @argv; if (GetOptions( 'user:s' => \my $user, 'password:s' => \my $password, 'dsn:s' => \my $dsn, 'verbose' => \my $verbose, 'force|f' => \my $force, 'sql:s' => \my $sql, 'bool' => \my $output_bool, 'string' => \my $output_string, 'help|h' => \my $help, 'man' => \my $man, )) { no warnings 'newline'; if( $sql and ! -f $sql ) { $sql = \"$sql", }; return { user => $user, password => $password, dsn => $dsn, verbose => $verbose, force => $force, sql => $sql, output_bool => $output_bool, output_string => $output_string, help => $help, man => $man, }; } else { return undef; }; } sub handle_command_line { my ($package,$appname,@argv) = @_; my $opts = $package->parse_command_line($appname,@argv) or pod2usage(2); pod2usage(1) if $opts->{help}; pod2usage(-verbose => 2) if $opts->{man}; $opts->{dsn} ||= sprintf 'dbi:SQLite:dbname=db/%s.sqlite', $appname; my( $dbh, $exitcode) = $package->create( %$opts ); return $exitcode } =head2 C<< DBIx::RunSQL->format_results %options >> my $sth= $dbh->prepare( 'select * from foo' ); $sth->execute(); print DBIx::RunSQL->format_results( sth => $sth ); Executes C<< $sth->fetchall_arrayref >> and returns the results either as tab separated string or formatted using L if the module is available. If you find yourself using this often to create reports, you may really want to look at L instead. =over 4 =item * C - the executed statement handle =item * C - if you want to force C or C usage, you can do it through that parameter. In fact, the module will use anything other than C as the class name and assume that the interface is compatible to C. =back Note that the query results are returned as one large string, so you really do not want to run this for large(r) result sets. =cut sub format_results { my( $self, %options )= @_; my $sth= delete $options{ sth }; if( ! exists $options{ formatter }) { if( eval { require "Text/Table.pm" }) { $options{ formatter }= 'Text::Table'; } else { $options{ formatter }= 'tab'; }; }; my @columns= @{ $sth->{NAME} }; my $no_header_when_empty = $options{ no_header_when_empty }; my $print_header = not exists $options{ header } || $options{ header }; my $res= $sth->fetchall_arrayref(); my $result=''; if( @columns ) { # Output as print statement if( $no_header_when_empty and ! @$res ) { # Nothing to do } elsif( 'tab' eq $options{ formatter } ) { $result = join "\n", $print_header ? join( "\t", @columns ) : (), map { join( "\t", @$_ ) } @$res ; } else { my $t= $options{formatter}->new(@columns); $t->load( @$res ); $result= $t; }; }; "$result"; # Yes, sorry - we stringify everything } =head2 C<< DBIx::RunSQL->split_sql ARGS >> my @statements= DBIx::RunSQL->split_sql( <<'SQL'); create table foo (name varchar(64)); create trigger foo_insert on foo before insert; new.name= 'foo-'||old.name; end; insert into foo name values ('bar'); SQL # Returns three elements This is a helper subroutine to split a sequence of (semicolon-newline-delimited) SQL statements into separate statements. It is documented because it is not a very smart subroutine and you might want to override or replace it. It might also be useful outside the context of L if you need to split up a large blob of SQL statements into smaller pieces. The subroutine needs the whole sequence of SQL statements in memory. If you are attempting to restore a large SQL dump backup into your database, this approach might not be suitable. =cut sub split_sql { my( $self, $sql )= @_; my @sql = split /;[ \t]*\r?\n/, $sql; # Because we blindly split above on /;\n/ # we need to reconstruct multi-line CREATE TRIGGER statements here again my @res; my $trigger; for my $statement (@sql) { next unless $statement =~ /\S/; if( $statement =~ /^\s*CREATE\s+TRIGGER\b/i ) { $trigger = $statement; next if( $statement !~ /END$/i ); $statement = $trigger; undef $trigger; } elsif( $trigger ) { $trigger .= ";\n$statement"; next if( $statement !~ /END$/i ); $statement = $trigger; undef $trigger; }; push @res, $statement; }; @res } 1; =head1 PROGRAMMER USAGE This module abstracts away the "run these SQL statements to set up your database" into a module. In some situations you want to give the setup SQL to a database admin, but in other situations, for example testing, you want to run the SQL statements against an in-memory database. This module abstracts away the reading of SQL from a file and allows for various command line parameters to be passed in. A skeleton C looks like this: #!/usr/bin/perl -w use strict; use lib 'lib'; use DBIx::RunSQL; my $exitcode = DBIx::RunSQL->handle_command_line('myapp'); exit $exitcode; =head1 NAME create-db.pl - Create the database =head1 ABSTRACT This sets up the database. The following options are recognized: =over 4 =item C<--user> USERNAME =item C<--password> PASSWORD =item C<--dsn> DSN The DBI DSN to use for connecting to the database =item C<--sql> SQLFILE The alternative SQL file to use instead of C. =item C<--force> Don't stop on errors =item C<--help> Show this message. =cut =head2 C<< DBIx::RunSQL->handle_command_line >> Parses the command line. This is a convenience method, which passes the following command line arguments to C<< ->create >>: --user --password --dsn --sql --force --verbose In addition, it handles the following switches through L: --help --man See also the section PROGRAMMER USAGE for a sample program to set up a database from an SQL file. =head1 NOTES =head2 COMMENT FILTERING The module tries to keep the SQL as much verbatim as possible. It filters all lines that end in semicolons but contain only SQL comments. All other comments are passed through to the database with the next statement. =head2 TRIGGER HANDLING This module uses a very simplicistic approach to recognize triggers. Triggers are problematic because they consist of multiple SQL statements and this module does not implement a full SQL parser. An trigger is recognized by the following sequence of lines CREATE TRIGGER ... END; If your SQL dialect uses a different syntax, it might still work to put the whole trigger on a single line in the input file. =head2 OTHER APPROACHES If you find yourself wanting to write SELECT statements, consider looking at L instead, which is geared towards that and even has an interface for Excel or HTML output. If you find yourself wanting to write parametrized queries as C<.sql> files, consider looking at L or potentially L. =head1 SEE ALSO L =head1 REPOSITORY The public repository of this module is L. =head1 SUPPORT The public support forum of this module is L. =head1 BUG TRACKER Please report bugs in this module via the RT CPAN bug queue at L or via mail to L. =head1 AUTHOR Max Maischein C =head1 COPYRIGHT (c) Copyright 2009-2016 by Max Maischein C. =head1 LICENSE This module is released under the same terms as Perl itself. =cut DBIx-RunSQL-0.15/MANIFEST0000644000175000017500000000065512731510600014045 0ustar corioncorion.gitignore Changes lib/DBIx/RunSQL.pm Makefile.PL MANIFEST This list of files MANIFEST.SKIP META.json META.yml README README.mkdn t/00-use.t t/01-force.t t/02-trigger.t t/03-comment.t t/04-handle-parameters.t t/05-output-bool.t t/05-select.t t/rt115442.t t/rt77378.sql t/rt77378.t t/trigger.sql xt/99-changes.t xt/99-compile.t xt/99-manifest.t xt/99-minimumversion.t xt/99-pod.t xt/99-todo.t xt/99-unix-text.t xt/99-versions.t DBIx-RunSQL-0.15/xt/0000755000175000017500000000000012731510603013344 5ustar corioncorionDBIx-RunSQL-0.15/xt/99-versions.t0000644000175000017500000000242212731510532015641 0ustar corioncorion#!perl -w # Stolen from ChrisDolan on use.perl.org # http://use.perl.org/comments.pl?sid=29264&cid=44309 use warnings; use strict; use File::Find; use Test::More; BEGIN { eval 'use File::Slurp; 1'; if ($@) { plan skip_all => "File::Slurp needed for testing"; exit 0; }; }; plan 'no_plan'; my $last_version = undef; sub check { return if (! m{blib/script/}xms && ! m{\.pm \z}xms); my $content = read_file($_); # only look at perl scripts, not sh scripts return if (m{blib/script/}xms && $content !~ m/\A \#![^\r\n]+?perl/xms); my @version_lines = $content =~ m/ ( [^\n]* \$VERSION \s* = [^=] [^\n]* ) /gxms; if (@version_lines == 0) { fail($_); } for my $line (@version_lines) { $line =~ s/^\s+//; $line =~ s/\s+$//; if (!defined $last_version) { $last_version = shift @version_lines; diag "Checking for $last_version"; pass($_); } else { is($line, $last_version, $_); } } } find({wanted => \&check, no_chdir => 1}, 'blib'); if (! defined $last_version) { fail('Failed to find any files with $VERSION'); } DBIx-RunSQL-0.15/xt/99-changes.t0000644000175000017500000000126412731510532015404 0ustar corioncorion#!perl -w use warnings; use strict; use File::Find; use Test::More tests => 2; =head1 PURPOSE This test ensures that the Changes file mentions the current version and that a release date is mentioned as well =cut my $module = 'DBIx::RunSQL'; (my $file = $module) =~ s!::!/!g; require "$file.pm"; my $version = sprintf '%0.2f', $module->VERSION; diag "Checking for version " . $version; my $changes = do { local $/; open my $fh, 'Changes' or die $!; <$fh> }; ok $changes =~ /^(.*$version.*)$/m, "We find version $version"; my $changes_line = $1; ok $changes_line =~ /$version\s+20\d{6}/, "We find a release date on the same line" or diag $changes_line; DBIx-RunSQL-0.15/xt/99-minimumversion.t0000644000175000017500000000044312731510532017053 0ustar corioncorion#!perl -w use strict; use Test::More; eval { require Test::MinimumVersion::Fast; Test::MinimumVersion::Fast->import; }; my @files; if ($@) { plan skip_all => "Test::MinimumVersion::Fast required for testing minimum Perl version"; } else { all_minimum_version_from_metayml_ok(); } DBIx-RunSQL-0.15/xt/99-compile.t0000644000175000017500000000137712731510532015431 0ustar corioncorion#!perl -w use warnings; use strict; use File::Find; use Test::More; BEGIN { eval 'use Capture::Tiny ":all"; 1'; if ($@) { plan skip_all => "Capture::Tiny needed for testing"; exit 0; }; }; plan 'no_plan'; my $last_version = undef; sub check { return if (! m{(\.pm|\.pl) \z}xmsi); my ($stdout, $stderr, $exit) = capture(sub { system( $^X, '-Mblib', '-wc', $_ ); }); s!\s*\z!! for ($stdout, $stderr); if( $exit ) { diag $exit; fail($_); } elsif( $stderr ne "$_ syntax OK") { diag $stderr; fail($_); } else { pass($_); }; } find({wanted => \&check, no_chdir => 1}, grep { -d $_ } 'blib', 'scripts', 'examples', 'bin', 'lib' ); DBIx-RunSQL-0.15/xt/99-todo.t0000644000175000017500000000202712731510532014737 0ustar corioncorionuse Test::More; use File::Spec; use File::Find; use strict; # Check that all files do not contain any # lines with "XXX" - such markers should # either have been converted into Todo-stuff # or have been resolved. # The test was provided by Andy Lester. my @files; my $blib = File::Spec->catfile(qw(blib lib)); find(\&wanted, grep { -d } ($blib, 'bin')); plan tests => 2* @files; foreach my $file (@files) { source_file_ok($file); } sub wanted { push @files, $File::Find::name if /\.p(l|m|od)$/; } sub source_file_ok { my $file = shift; open( my $fh, "<$file" ) or die "Can't open $file: $!"; my @lines = <$fh>; close $fh; my $n = 0; for ( @lines ) { ++$n; s/^/$file ($n): /; } my @x = grep /XXX/, @lines; if ( !is( scalar @x, 0, "Looking for XXXes in $file" ) ) { diag( $_ ) for @x; } @x = grep /<<<|>>>/, @lines; if ( !is( scalar @x, 0, "Looking for <<<<|>>>> in $file" ) ) { diag( $_ ) for @x; } } DBIx-RunSQL-0.15/xt/99-unix-text.t0000644000175000017500000000140412731510532015735 0ustar corioncorionuse Test::More; # Check that all released module files are in # UNIX text format use File::Spec; use File::Find; use strict; my @files; my $blib = File::Spec->catfile(qw(blib lib)); find(\&wanted, grep { -d } ($blib, 'bin')); plan tests => scalar @files; foreach my $file (@files) { unix_file_ok($file); } sub wanted { push @files, $File::Find::name if /\.p(l|m|od)$/; } sub unix_file_ok { my ($filename) = @_; local $/; open F, "< $filename" or die "Couldn't open '$filename' : $!\n"; binmode F; my $content = ; my $i; my @lines = grep { /\x0D\x0A$/sm } map { sprintf "%s: %s\x0A", $i++, $_ } split /\x0A/, $content; unless (is(scalar @lines, 0,"'$filename' contains no windows newlines")) { diag $_ for @lines; }; close F; }; DBIx-RunSQL-0.15/xt/99-pod.t0000644000175000017500000000123212731510532014551 0ustar corioncorionuse Test::More; # Check our Pod # The test was provided by Andy Lester, # who stole it from Brian D. Foy # Thanks to both ! use File::Spec; use File::Find; use strict; eval { require Test::Pod; Test::Pod->import; }; my @files; if ($@) { plan skip_all => "Test::Pod required for testing POD"; } elsif ($Test::Pod::VERSION < 0.95) { plan skip_all => "Test::Pod 0.95 required for testing POD"; } else { my $blib = File::Spec->catfile(qw(blib lib)); find(\&wanted, grep { -d } ($blib, 'bin')); plan tests => scalar @files; foreach my $file (@files) { pod_file_ok($file); } } sub wanted { push @files, $File::Find::name if /\.p(l|m|od)$/; } DBIx-RunSQL-0.15/xt/99-manifest.t0000644000175000017500000000154612731510532015605 0ustar corioncorionuse strict; use Test::More; # Check that MANIFEST and MANIFEST.skip are sane : use File::Find; use File::Spec; my @files = qw( MANIFEST MANIFEST.SKIP ); plan tests => scalar @files * 4 +1 # MANIFEST existence check ; for my $file (@files) { ok(-f $file, "$file exists"); open F, "<$file" or die "Couldn't open $file : $!"; my @lines = ; is_deeply([grep(/^$/, @lines)],[], "No empty lines in $file"); is_deeply([grep(/^\s+$/, @lines)],[], "No whitespace-only lines in $file"); is_deeply([grep(/^\s*\S\s+$/, @lines)],[],"No trailing whitespace on lines in $file"); if ($file eq 'MANIFEST') { chomp @lines; is_deeply([grep { s/\s.*//; ! -f } @lines], [], "All files in $file exist") or do { diag "$_ is mentioned in $file but doesn't exist on disk" for grep { ! -f } @lines }; }; close F; }; DBIx-RunSQL-0.15/Makefile.PL0000644000175000017500000000504712731510532014672 0ustar corioncorion# -*- mode: perl; c-basic-offset: 4; indent-tabs-mode: nil; -*- #use 5.006; #weaken use ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. WriteMakefile1( MIN_PERL_VERSION => '5.006', META_MERGE => { resources => { repository => 'http://github.com/Corion/dbix--runsql', bugtracker => 'http://rt.cpan.org/Public/Dist/Display.html?Name=DBIx-RunSQL', license => 'http://dev.perl.org/licenses/', }, }, 'NAME' => 'DBIx::RunSQL', 'LICENSE' => 'perl', 'VERSION_FROM' => 'lib/DBIx/RunSQL.pm', # finds $VERSION 'PREREQ_PM' => { 'DBI' => 0, }, # e.g., Module::Name => 1.1 ABSTRACT_FROM => 'lib/DBIx/RunSQL.pm', # retrieve abstract from module AUTHOR => 'Max Maischein ', ); 1; sub WriteMakefile1 { #Written by Alexandr Ciornii, version 0.21. Added by eumm-upgrade. my %params=@_; regen_README( $params{VERSION_FROM} ); my $eumm_version=$ExtUtils::MakeMaker::VERSION; $eumm_version=eval $eumm_version; die "EXTRA_META is deprecated" if exists $params{EXTRA_META}; die "License not specified" if not exists $params{LICENSE}; if ($params{BUILD_REQUIRES} and $eumm_version < 6.5503) { #EUMM 6.5502 has problems with BUILD_REQUIRES $params{PREREQ_PM}={ %{$params{PREREQ_PM} || {}} , %{$params{BUILD_REQUIRES}} }; delete $params{BUILD_REQUIRES}; } delete $params{CONFIGURE_REQUIRES} if $eumm_version < 6.52; delete $params{MIN_PERL_VERSION} if $eumm_version < 6.48; delete $params{META_MERGE} if $eumm_version < 6.46; delete $params{META_ADD} if $eumm_version < 6.46; delete $params{LICENSE} if $eumm_version < 6.31; delete $params{AUTHOR} if $] < 5.005; delete $params{ABSTRACT_FROM} if $] < 5.005; delete $params{BINARY_LOCATION} if $] < 5.005; WriteMakefile(%params); } sub regen_README { eval { require Pod::Readme; my $parser = Pod::Readme->new(); # Read POD from Module.pm and write to README $parser->parse_from_file($_[0], 'README'); }; eval { require Pod::Markdown; my $parser = Pod::Markdown->new(); # Read POD from Module.pm and write to README $parser->parse_from_file($_[0]); open my $fh, '>', 'README.mkdn' or die "Couldn't open 'README.mkdn': $!"; print $fh $parser->as_markdown; }; }