Skip to content

Commit

Permalink
add Schema::Dumper.
Browse files Browse the repository at this point in the history
  • Loading branch information
nekokak committed Jan 14, 2011
1 parent 4d712d7 commit 394feba
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 0 deletions.
83 changes: 83 additions & 0 deletions lib/Teng/Schema/Dumper.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package Teng::Schema::Dumper;
use strict;
use warnings;
use DBIx::Inspector 0.03;
use Carp ();

sub dump {
my $class = shift;
my %args = @_==1 ? %{$_[0]} : @_;

my $dbh = $args{dbh} or Carp::croak("missing mandatory parameter 'dbh'");
my $namespace = $args{namespace} or Carp::croak("missing mandatory parameter 'namespace'");

my $inspector = DBIx::Inspector->new(dbh => $dbh);

my $ret = "package ${namespace}::Schema;\n";
$ret .= "use Teng::Schema::Declare;\n";
for my $table_info (sort { $_->name } $inspector->tables) {
$ret .= "table {\n";
$ret .= sprintf(" name '%s';\n", $table_info->name);
$ret .= sprintf(" pk %s;\n", join ',' , map { q{'}.$_->name.q{'} } $table_info->primary_key);
$ret .= " columns qw/\n";
$ret .= join("\n", map { q{ }.$_->name } $table_info->columns)."\n";
$ret .= " /;\n";
$ret .= "};\n\n";
}
$ret .= "1;\n";
return $ret;
}

1;
__END__
=head1 NAME
Teng::Schema::Dumper - Schema code generator
=head1 SYNOPSIS
use DBI;
use Teng::Schema::Dumper;
my $dbh = DBI->connect(@dsn) or die;
print Teng::Schema::Dumper->dump(dbh => $dbh, namespace => 'Mock::DB');
=head1 DESCRIPTION
This module generates the Perl code to generate L<Teng::Schema> instance.
You can use it by C<do "my/schema.pl"> or embed it to the package.
B<THIS MODULE IS HIGHLY EXPERIMENTAL. DO NOT USE THIS FOR PRODUCTION ENVIRONMENT.>
=head1 METHODS
=over 4
=item Teng::Dumper->dump(dbh => $dbh, table2class_cb => \&code);
This is the method to generate code from DB. It returns the Perl5 code in string.
The arguments are:
=over 4
=item dbh
Database handle from DBI.
=item table2class_cb
Coderef to convert table name to row class name.
The method is calling with following form:
my $class_name = $code->($table_name);
=back
=back
45 changes: 45 additions & 0 deletions t/001_basic/004_schema_dumper.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use strict;
use warnings;
use Test::More;
use Test::Requires 'DBD::SQLite';
use DBI;
use Teng;
use Teng::Schema::Dumper;

# initialize
my $dbh = DBI->connect('dbi:SQLite:', '', '', {RaiseError => 1}) or die 'cannot connect to db';
$dbh->do(q{
create table user (
user_id integer primary key,
name varchar(255),
email varchar(255),
created_on int
);
});


# generate schema and eval.
my $code = Teng::Schema::Dumper->dump(
dbh => $dbh,
namespace => 'Mock::DB',
);
my $schema = eval $code;
::ok !$@, 'no syntax error';
diag $@ if $@;

{
package Mock::DB;
use parent 'Teng';
}

my $db = Mock::DB->new(dbh => $dbh);
my $user = $db->schema->get_table('user');
is($user->name, 'user');
is(join(',', @{$user->primary_keys}), 'user_id');
is(join(',', @{$user->columns}), 'user_id,name,email,created_on');

my $row = $db->schema->get_row_class('user');
isa_ok $row, 'Mock::DB::Row::User';

done_testing;

0 comments on commit 394feba

Please sign in to comment.