DBIx-Class-ResultDDL

 view release on metacpan or  search on metacpan

lib/DBIx/Class/ResultDDL.pm  view on Meta::CPAN

  col
    null default auto_inc fk
    integer unsigned tinyint smallint bigint decimal numeric money
    float float4 float8 double real
    char varchar nchar nvarchar MAX binary varbinary bit varbit
    blob tinyblob mediumblob longblob text tinytext mediumtext longtext ntext bytea
    date datetime timestamp enum bool boolean
    uuid json jsonb inflate_json array
  primary_key idx create_index unique sqlt_add_index sqlt_add_constraint
  rel_one rel_many has_one might_have has_many belongs_to many_to_many
    ddl_cascade dbic_cascade
);

our %EXPORT_TAGS;
$EXPORT_TAGS{V2}= \@V2;
export @V2;


sub table {
	my $name= shift;
	DBIx::Class::Core->can('table')->(scalar($CALLER||caller), $name);

lib/DBIx/Class/ResultDDL.pm  view on Meta::CPAN

				accessor => ($reltype eq 'rel_one'? 'single' : 'multi'),
				join_type => 'LEFT',
				($is_f_key? (
					fk_columns => { map { do {(my $x= $_) =~ s/^self\.//; $x } => 1 } values %$dbic_colmap },
					is_depends_on => 1,
					is_foreign_key_constraint => 1,
					undef_on_null_fk => 1,
				) : (
					is_depends_on => 0,
				)),
				cascade_copy => 0, cascade_delete => 0,
				%$opts
			}
		);
	} else {
		require DBIx::Class::Core;
		DBIx::Class::Core->can($reltype)->($pkg, $relname, $rel_pkg, $dbic_colmap, $opts);
	}
}


sub ddl_cascade {
	my $mode= shift;
	$mode= 'CASCADE' if !defined $mode || $mode eq '1';
	$mode= 'RESTRICT' if $mode eq '0';
	return
		on_update => $mode,
		on_delete => $mode;
}


sub dbic_cascade {
	my $mode= defined $_[0]? $_[0] : 1;
	return
		cascade_copy => $mode,
		cascade_delete => $mode;
}


sub view {
        my ($name, $definition, %opts) = @_;
        my $pkg= $CALLER || caller;
        DBIx::Class::Core->can('table_class')->($pkg, 'DBIx::Class::ResultSource::View');
        DBIx::Class::Core->can('table')->($pkg, $name);

        my $rsi = $pkg->result_source_instance;

lib/DBIx/Class/ResultDDL.pm  view on Meta::CPAN

  col
    null default auto_inc fk
    integer unsigned tinyint smallint bigint decimal numeric money
    float float4 float8 double real
    char varchar nchar nvarchar MAX binary varbinary bit varbit
    blob tinyblob mediumblob longblob text tinytext mediumtext longtext ntext bytea
    date datetime timestamp enum bool boolean
    uuid json jsonb inflate_json array
  primary_key idx create_index unique sqlt_add_index sqlt_add_constraint
  rel_one rel_many has_one might_have has_many belongs_to many_to_many
    ddl_cascade dbic_cascade

=head2 C<:V1>

See L<DBIx::Class::ResultDDL::V1>.  The primary difference from V2 is a bug in
C<datetime($timezone)> where the timezone generated the wrong DBIC arguments.
Also it didn't support C<-retrieve_defaults>.

=head2 C<:V0>

See L<DBIx::Class::ResultDDL::V0>.  The primary difference from V1 is lack of array

lib/DBIx/Class/ResultDDL.pm  view on Meta::CPAN


  rel_one $name => $peer_class, $condition, @attr_list;
  rel_one $name => { $mycol => "$ResultClass.$fcol", ... }, @attr_list;
  rel_one $name => 'JOIN $peer_class ON $sql', @attr_list;
  # becomes...
  __PACKAGE__->add_relationship(
    $rel_name, $peer_class, { "foreign.$fcol" => "self.$mycol" },
    {
      join_type => 'LEFT',
      accessor => 'single',
      cascade_copy => 0,
      cascade_delete => 0,
      is_depends_on => $is_f_pk, # auto-detected, unless specified
      ($is_f_pk? fk_columns => { $mycol => 1 } : ()),
      @attr_list
    }
  );

=head2 rel_many

  rel_many $name => { $my_col => "$class.$col", ... }, @attr_list;
  rel_many $name => 'JOIN $peer_class ON $sql', @attr_list;

Same as L</rel_one>, but generates a one-to-many relation with a multi-accessor.

=head2 ddl_cascade

  ddl_cascade;     # same as ddl_cascade("CASCADE");
  ddl_cascade(1);  # same as ddl_cascade("CASCADE");
  ddl_cascade(0);  # same as ddl_cascade("RESTRICT");
  ddl_cascade($mode);

Helper method to generate C<@options> for above.  It generates

  on_update => $mode, on_delete => $mode

This does not affect client-side cascade, and is only used by Schema::Loader to generate DDL
for the foreign keys when the table is deployed.

=head2 dbic_cascade

  dbic_cascade;  # same as dbic_cascade(1)
  dbic_cascade($enabled);

Helper method to generate C<@options> for above.  It generates

  cascade_copy => $enabled, cascade_delete => $enabled

This re-enables the dbic-side cascading that was disabled by default in the C<rel_> functions.

=head2 view

  view $view_name, $view_sql, %options;

Makes the current resultsource into a view. This is used instead of
'table'. Takes two options, 'is_virtual', to make this into a
virtual view, and  'depends' to list tables this view depends on.

lib/DBIx/Class/ResultDDL/SchemaLoaderMixin.pm  view on Meta::CPAN


sub generate_relationship_attr_sugar {
	my ($self, $orig_options)= @_;
	my %options= %$orig_options;
	my @expr;
	if (defined $options{on_update} && defined $options{on_delete}
		&& $options{on_update} eq $options{on_delete}
	) {
		my $val= delete $options{on_update};
		delete $options{on_delete};
		push @expr, $val eq 'CASCADE'? 'ddl_cascade'
			: $val eq 'RESTRICT'? 'ddl_cascade(0)'
			: 'ddl_cascade('.deparse($val).')'
	}
	if (defined $options{cascade_copy} && defined $options{cascade_delete}
		&& $options{cascade_copy} eq $options{cascade_delete}
	) {
		my $val= delete $options{cascade_copy};
		delete $options{cascade_delete};
		push @expr, $val eq '1'? 'dbic_cascade'
			: 'dbic_cascade('.deparse($val).')'
	}
	push @expr, substr(deparse(\%options),2,-2) if keys %options;
	return join ', ', @expr
}

my %rel_methods= map +($_ => 1), qw( belongs_to might_have has_one has_many );
sub _dbic_stmt {
	my ($self, $class, $method)= splice(@_, 0, 3);
	# The first time we generate anything for each class, inject the 'use' line.
	$self->_raw_stmt($class, $self->generate_resultddl_import_line($class))

lib/DBIx/Class/ResultDDL/V0.pm  view on Meta::CPAN

my @V0= qw(
	table
	col
	  null default auto_inc fk
	  integer unsigned tinyint smallint bigint decimal numeric
	  char varchar nchar nvarchar binary varbinary blob text ntext
	  date datetime timestamp enum bool boolean
	  inflate_json
	primary_key
	rel_one rel_many has_one might_have has_many belongs_to many_to_many
	  ddl_cascade dbic_cascade
);
our %EXPORT_TAGS;
$EXPORT_TAGS{V0}= \@V0;
export @V0;


sub null       { is_nullable => 1 }
sub auto_inc   { is_auto_increment => 1 }
sub fk         { is_foreign_key => 1 }

lib/DBIx/Class/ResultDDL/V0.pm  view on Meta::CPAN

feature to "off".

  rel_one $rel_name, $peer_class, $condition, @attr_list;
  rel_one $rel_name, { $mycol => "$ResultClass.$fcol", ... }, @attr_list;
  # becomes...
  __PACKAGE__->add_relationship(
    $rel_name, $peer_class, { "foreign.$fcol" => "self.$mycol" },
    {
      join_type => 'LEFT',
      accessor => 'single',
      cascade_copy => 0,
      cascade_delete => 0,
      is_depends_on => $is_f_pk, # auto-detected, unless specified
      ($is_f_pk? fk_columns => { $mycol => 1 } : ()),
      @attr_list
    }
  );

=head2 rel_many

  rel_many $name => { $my_col => "$class.$col", ... }, @options;

Same as L</rel_one>, but generates a one-to-many relation with a multi-accessor.

=head2 ddl_cascade

  ddl_cascade;     # same as ddl_cascade("CASCADE");
  ddl_cascade(1);  # same as ddl_cascade("CASCADE");
  ddl_cascade(0);  # same as ddl_cascade("RESTRICT");
  ddl_cascade($mode);

Helper method to generate C<@options> for above.  It generates

  on_update => $mode, on_delete => $mode

This does not affect client-side cascade, and is only used by Schema::Loader to generate DDL
for the foreign keys when the table is deployed.

=head2 dbic_cascade

  dbic_cascade;  # same as dbic_cascade(1)
  dbic_cascade($enabled);

Helper method to generate C<@options> for above.  It generates

  cascade_copy => $enabled, cascade_delete => $enabled

This re-enables the dbic-side cascading that was disabled by default in the C<rel_> functions.

=head1 MISSING FUNCTIONALITY

The methods above in most cases allow you to insert plain-old-DBIC notation
where appropriate, instead of relying purely on sugar methods.
If you are missing your favorite column flag or something, feel free to
contribute a patch.

lib/DBIx/Class/ResultDDL/V1.pm  view on Meta::CPAN

  col
    null default auto_inc fk
    integer unsigned tinyint smallint bigint decimal numeric money
    float float4 float8 double real
    char varchar nchar nvarchar MAX binary varbinary bit varbit
    blob tinyblob mediumblob longblob text tinytext mediumtext longtext ntext bytea
    date datetime timestamp enum bool boolean
    uuid json jsonb inflate_json array
  primary_key idx create_index unique sqlt_add_index sqlt_add_constraint
  rel_one rel_many has_one might_have has_many belongs_to many_to_many
    ddl_cascade dbic_cascade
);

our %EXPORT_TAGS;
$EXPORT_TAGS{V1}= \@V1;
export @V1;


*_maybe_timezone= *DBIx::Class::ResultDDL::_maybe_timezone;
*_maybe_array=    *DBIx::Class::ResultDDL::_maybe_array;
sub datetime    { my $tz= &_maybe_timezone; data_type => 'datetime'.&_maybe_array, ($tz? (time_zone => $tz) : ()), @_ }

lib/DBIx/Class/ResultDDL/V1.pm  view on Meta::CPAN

feature to "off".

  rel_one $rel_name, $peer_class, $condition, @attr_list;
  rel_one $rel_name, { $mycol => "$ResultClass.$fcol", ... }, @attr_list;
  # becomes...
  __PACKAGE__->add_relationship(
    $rel_name, $peer_class, { "foreign.$fcol" => "self.$mycol" },
    {
      join_type => 'LEFT',
      accessor => 'single',
      cascade_copy => 0,
      cascade_delete => 0,
      is_depends_on => $is_f_pk, # auto-detected, unless specified
      ($is_f_pk? fk_columns => { $mycol => 1 } : ()),
      @attr_list
    }
  );

=head2 rel_many

  rel_many $name => { $my_col => "$class.$col", ... }, @options;

Same as L</rel_one>, but generates a one-to-many relation with a multi-accessor.

=head2 ddl_cascade

  ddl_cascade;     # same as ddl_cascade("CASCADE");
  ddl_cascade(1);  # same as ddl_cascade("CASCADE");
  ddl_cascade(0);  # same as ddl_cascade("RESTRICT");
  ddl_cascade($mode);

Helper method to generate C<@options> for above.  It generates

  on_update => $mode, on_delete => $mode

This does not affect client-side cascade, and is only used by Schema::Loader to generate DDL
for the foreign keys when the table is deployed.

=head2 dbic_cascade

  dbic_cascade;  # same as dbic_cascade(1)
  dbic_cascade($enabled);

Helper method to generate C<@options> for above.  It generates

  cascade_copy => $enabled, cascade_delete => $enabled

This re-enables the dbic-side cascading that was disabled by default in the C<rel_> functions.

=head2 view

  view $view_name, $view_sql, %options;

Makes the current resultsource into a view. This is used instead of
'table'. Takes two options, 'is_virtual', to make this into a
virtual view, and  'depends' to list tables this view depends on.

t/10-schema-loader-mixin.t  view on Meta::CPAN

);
SQL
undef $db;

my %loader_options= (
	debug => 1,
	dump_directory => "$tmpdir/lib",
	naming => 'v7',
	relationship_attrs => {
		has_many => {
			cascade_delete => 0,
			cascade_copy   => 0,
		},
		might_have => {
			cascade_delete => 0,
			cascade_copy   => 0,
		},
		belongs_to => {
			on_delete => 'CASCADE',
			on_update => 'CASCADE',
			is_deferrable => 1,
		},
	},
);

subtest standard => sub {

t/10-schema-loader-mixin.t  view on Meta::CPAN

PL

	# Verify has_many & belongs_to between artist and album
	my $artist_src= slurp("$tmpdir/lib/My/Schema/Result/Artist.pm");
	my $album_src=  slurp("$tmpdir/lib/My/Schema/Result/Album.pm");
	verify_contains_lines( $artist_src, <<'PL', 'Result::Artist.pm' ) or diag "Unexpected sourcecode:\n$artist_src";
	table 'artist';
	col name => varchar(100);
	primary_key 'name';
	
	has_many albums => { name => 'Album.artist_name' }, dbic_cascade(0);
PL
	verify_contains_lines( $album_src, <<'PL', 'Result::Album.pm' ) or diag "Unexpected sourcecode:\n$album_src";
	table 'album';
	col artist_name  => varchar(100), fk;
	col album_name   => varchar(255);
	col release_date => datetime;
	primary_key 'artist_name', 'album_name';
	
	belongs_to artist_name => { artist_name => 'Artist.name' }, ddl_cascade, is_deferrable => 1;
PL
};

subtest with_inflate_json => sub {
	plan skip_all => 'Require DBIx::Class::InflateColumn::Serializer::JSON for this test'
		unless $can_inflate_json;

	# Run Schema Loader on the SQLite database
	DBIx::Class::Schema::Loader::make_schema_at(
		'My::SchemaWithJson',



( run in 1.067 second using v1.01-cache-2.11-cpan-49f99fa48dc )