Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New exclude_columns option #18

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion lib/DBIx/Class/Schema/Loader/Base.pm
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use DBIx::Class::Schema::Loader::Optional::Dependencies ();
use Try::Tiny;
use DBIx::Class ();
use Encode qw/encode decode/;
use List::Util qw/all any none/;
use List::Util qw/all any none pairgrep/;
use File::Temp 'tempfile';
use curry;
use namespace::clean;
Expand All @@ -49,6 +49,7 @@ __PACKAGE__->mk_group_ro_accessors('simple', qw/
moniker_map
col_accessor_map
custom_column_info
exclude_columns
inflect_singular
inflect_plural
debug
Expand Down Expand Up @@ -905,6 +906,22 @@ Omit the package version from the signature comment.

Omit the creation timestamp from the signature comment.

=head2 exclude_columns

Hook for excluding some columns from the generated schema.

Receives the L<DBIx::Class::Schema::Loader::Table> object, column name and
column_info. This is called at the last possible moment before emitting an
C<add_columns> call; in particular, it happens after L</custom_column_info>.

For example, to exclude columns of type "tsvector" (which might be useful in
a PostgreSQL database where those columns are maintained by triggers):

exclude_columns => sub {
my ($table, $column_name, $column_info) = @_;
return $column_info->{data_type} eq 'tsvector';
},

=head2 custom_column_info

Hook for adding extra attributes to the
Expand Down Expand Up @@ -1254,6 +1271,10 @@ sub new {
croak 'custom_column_info must be a CODE ref';
}

if ($self->exclude_columns && ref $self->exclude_columns ne 'CODE') {
croak 'exclude_columns must be a CODE ref';
}

$self->_check_back_compat;

$self->use_namespaces(1) unless defined $self->use_namespaces;
Expand Down Expand Up @@ -2710,9 +2731,12 @@ sub _setup_src_meta {
$col_info->{$pkcol}{is_nullable} = 0;
}

my $exclude_columns = $self->exclude_columns;

$self->_dbic_stmt(
$table_class,
'add_columns',
pairgrep { !$exclude_columns || !$exclude_columns->($table, $a, $b) }
map { $_, ($col_info->{$_}||{}) } @$cols
);

Expand Down
34 changes: 32 additions & 2 deletions t/lib/dbixcsl_common_tests.pm
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ sub run_tests {
my $col_accessor_map_tests = 6;

plan tests => @connect_info *
(233 + $col_accessor_map_tests + $extra_count + ($self->{data_type_tests}{test_count} || 0));
(237 + $col_accessor_map_tests + $extra_count + ($self->{data_type_tests}{test_count} || 0));

foreach my $info_idx (0..$#connect_info) {
my $info = $connect_info[$info_idx];
Expand Down Expand Up @@ -248,6 +248,7 @@ sub setup_schema {
inflect_singular => { fkid => 'fkid_singular' },
moniker_map => \&_monikerize,
custom_column_info => \&_custom_column_info,
exclude_columns => \&_exclude_columns,
debug => $debug,
dump_directory => DUMP_DIR,
datetime_timezone => 'Europe/Berlin',
Expand Down Expand Up @@ -289,7 +290,7 @@ sub setup_schema {
my $standard_sources = not defined $expected_count;

if ($standard_sources) {
$expected_count = 41;
$expected_count = 42;

if (not ($self->{vendor} eq 'mssql' && $connect_info->[0] =~ /Sybase/)) {
$expected_count++ for @{ $self->{data_type_tests}{table_names} || [] };
Expand Down Expand Up @@ -736,6 +737,10 @@ qr/\n__PACKAGE__->load_components\("TestSchemaComponent", "\+TestSchemaComponent
my $class37 = $classes->{loader_test37};
my $rsobj37 = $conn->resultset($moniker37);

my $moniker38 = $monikers->{loader_test38};
my $class38 = $classes->{loader_test38};
my $rsobj38 = $conn->resultset($moniker38);

my $moniker42 = $monikers->{loader_test42};
my $class42 = $classes->{loader_test42};
my $rsobj42 = $conn->resultset($moniker42);
Expand Down Expand Up @@ -773,6 +778,7 @@ qr/\n__PACKAGE__->load_components\("TestSchemaComponent", "\+TestSchemaComponent
isa_ok( $rsobj34, "DBIx::Class::ResultSet" );
isa_ok( $rsobj36, "DBIx::Class::ResultSet" );
isa_ok( $rsobj37, "DBIx::Class::ResultSet" );
isa_ok( $rsobj38, "DBIx::Class::ResultSet" );
isa_ok( $rsobj42, "DBIx::Class::ResultSet" );
isa_ok( $rsobj43, "DBIx::Class::ResultSet" );
isa_ok( $rsobj44, "DBIx::Class::ResultSet" );
Expand Down Expand Up @@ -1007,6 +1013,12 @@ qr/\n__PACKAGE__->load_components\("TestSchemaComponent", "\+TestSchemaComponent
ok( $class37->relationship_info('parent'), 'parents rel created' );
ok( $class37->relationship_info('child'), 'child rel created' );

ok (!$class38->has_column('b_char_as_data'),
'column loader_test38.b_char_as_data correctly excluded' );
ok( $class38->has_column($_),
"column loader_test38.$_ correctly included" )
for qw/a_char_as_data b_int/;

is_deeply($class32->_m2m_metadata, {}, 'many_to_many not created for might_have');
is_deeply($class34->_m2m_metadata, {}, 'many_to_many not created for might_have');

Expand Down Expand Up @@ -1657,6 +1669,16 @@ sub create {
c_char_as_data VARCHAR(100)
) $self->{innodb}
},

qq{
CREATE TABLE loader_test38 (
id INTEGER NOT NULL PRIMARY KEY,
a_char_as_data VARCHAR(100),
b_char_as_data VARCHAR(100),
b_int INTEGER
) $self->{innodb}
},

# DB2 does not allow nullable uniq components, SQLAnywhere automatically
# converts nullable uniq components to NOT NULL
qq{
Expand Down Expand Up @@ -2173,6 +2195,7 @@ sub drop_tables {
LoAdEr_test24
loader_test35
loader_test36
loader_test38
loader_test50
/;

Expand Down Expand Up @@ -2345,6 +2368,13 @@ sub _custom_column_info {
return;
}

sub _exclude_columns {
my ( $table, $column_name, $column_info ) = @_;
return lc $table eq 'loader_test38'
&& $column_name =~ /^b_/i
&& $column_info->{data_type} =~ /char/i;
}

my %DATA_TYPE_MULTI_TABLE_OVERRIDES = (
oracle => qr/\blong\b/i,
mssql => qr/\b(?:timestamp|rowversion)\b/i,
Expand Down