-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
128 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
|