Rose::DBx::Object::MoreHelpers - more mixin helpers for RDBO


Rose-DBx-Object-MoreHelpers documentation Contained in the Rose-DBx-Object-MoreHelpers distribution.

Index


Code Index:

NAME

Top

Rose::DBx::Object::MoreHelpers - more mixin helpers for RDBO

SYNOPSIS

Top

 package MyRDBO;
 use base qw( Rose::DB::Object );
 use Rose::DBx::Object::MoreHelpers;

DESCRIPTION

Top

In the tradition of Rose::DB::Object::Helpers, more importable methods.

This class inherits from Rose::Object::MixIn. See the Rose::Object::MixIn documentation for a full explanation of how to import methods from this class. The helper methods themselves are described below.

METHODS

Top

MoreHelpers changes the default relationship method makers to include:

 find
 get_set_on_save
 add_on_save
 count
 iterator

primary_key_uri_escaped

Returns the primary key value, URI-escaped. If there are multiple columns comprising the primary key, they are joined into a single string.

If there are no values set for any of the column(s) comprising the primary key, returns 0.

Otherwise, returns all column values joined with ;; as per CatalystX::CRUD::Controller API.

primary_key_value

Returns the value of the primary key column(s). If the value is comprised of multiple column values, the return value will be an array ref of values.

unique_value

Returns the first single-column unique value from the object by default. This is intended for the common case where you use a serial integer as the primary key but want to display a more human-friendly value programmatically, like a name.

If no unique single-column values are found, returns the primary_key_value().

moniker

Returns the name of the class without any leading namespace qualifier. Similar to the DBIx::Class concept of 'moniker'.

flatten( args )

Returns the serialized object and its immediately related objects.

As of version 0.03, this is just a wrapper around the as_tree() Helper method with the "force_load" arg set to true. args are passed directly to the as_tree() method.

Requires RDBO 0.7712 or later.

exists( [ @params ] )

Returns true if the object exists in the database, false otherwise.

May be called as class or object method.

This method uses the Rose::DB::Object::Manager class to check the database based on non-unique column(s). Call it like you would load_speculative() but when you do not have a unique combination of columns (which all the load* methods require).

When called as object method, if @params is omitted, the current column values of the object are used.

Example:

 # 'title' has no unique constraints on it
 my $object = Object->new(title => 'Foo');
 $object->save unless $object->exists;

NOTE: Using exists() as a way of enforcing data integrity is far inferior to actually placing a constraint on a table in the database. However, for things like testing and development data, it can be a useful utility method.

fetch_all

Shortcut for the Manager method get_objects().

fetch_all_iterator

Shortcut for the Manager method get_objects_iterator().

column_is_boolean( column_name )

Returns true if the column type for column_name is 'boolean'.

AUTHOR

Top

Peter Karman, <karman at cpan.org>

BUGS

Top

Please report any bugs or feature requests to bug-rose-dbx-object-morehelpers at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Rose-DBx-Object-MoreHelpers. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

Top

You can find documentation for this module with the perldoc command.

    perldoc Rose::DBx::Object::MoreHelpers

You can also look for information at:

* AnnoCPAN: Annotated CPAN documentation

http://annocpan.org/dist/Rose-DBx-Object-MoreHelpers

* CPAN Ratings

http://cpanratings.perl.org/d/Rose-DBx-Object-MoreHelpers

* RT: CPAN's request tracker

http://rt.cpan.org/NoAuth/Bugs.html?Dist=Rose-DBx-Object-MoreHelpers

* Search CPAN

http://search.cpan.org/dist/Rose-DBx-Object-MoreHelpers

ACKNOWLEDGEMENTS

Top

The Minnesota Supercomputing Institute http://www.msi.umn.edu/ sponsored the development of this software.

COPYRIGHT & LICENSE

Top


Rose-DBx-Object-MoreHelpers documentation Contained in the Rose-DBx-Object-MoreHelpers distribution.
package Rose::DBx::Object::MoreHelpers;

use warnings;
use strict;

use Rose::Object::MixIn;
our @ISA = qw(Rose::Object::MixIn);

use Carp;
use Data::Dump qw( dump );
use Scalar::Util qw( blessed );

use Rose::DB::Object::Manager;
use Rose::DB::Object::Metadata::Relationship::OneToMany;
Rose::DB::Object::Metadata::Relationship::OneToMany
    ->default_auto_method_types(
    qw(
        find
        get_set_on_save
        add_on_save
        count
        iterator
        )
    );
use Rose::DB::Object::Metadata::Relationship::ManyToMany;
Rose::DB::Object::Metadata::Relationship::ManyToMany
    ->default_auto_method_types(
    qw(
        find
        get_set_on_save
        add_on_save
        count
        iterator
        )
    );

use Rose::Class::MakeMethods::Generic ( scalar => ['debug'], );

our $VERSION = '0.08';

__PACKAGE__->export_tags(
    all => [
        qw(
            primary_key_uri_escaped primary_key_value
            flatten exists has_related has_related_pages
            fetch_all fetch_all_iterator
            )
    ],

    # This exists for the benefit of the test suite
    all_noprereq => [
        qw(
            primary_key_uri_escaped primary_key_value
            flatten exists has_related has_related_pages
            fetch_all fetch_all_iterator
            )
    ],
);

sub primary_key_uri_escaped {
    my $self = shift;
    my $val  = $self->primary_key_value;
    my @vals = ref $val ? @$val : ($val);
    my @esc;
    for my $v (@vals) {
        $v = '' unless defined $v;
        $v =~ s/;/\%3b/g;
        push @esc, $v;
    }
    if ( !grep { length($_) } @esc ) {
        return 0;
    }
    my $pk = join( ';;', @esc );
    $pk =~ s!/!\%2f!g;
    return $pk;
}

sub primary_key_value {
    my $self = shift;
    my @cols = $self->meta->primary_key_column_names;
    my @vals;
    for my $m (@cols) {
        push( @vals, scalar $self->$m );
    }
    return scalar(@vals) > 1 ? \@vals : $vals[0];
}

sub unique_value {
    my $self  = shift;
    my @ukeys = $self->meta->unique_keys_column_names;
    if (@ukeys) {
        for my $k (@ukeys) {
            if ( scalar(@$k) == 1 ) {
                my $method = $k->[0];
                return $self->$method;    # TODO column alias ??
            }
        }
    }
    return $self->primary_key_value;
}

sub moniker {
    my $self  = shift;
    my $class = $self->meta->class;
    $class =~ s/^.+:://;
    return $class;
}

sub flatten {
    my $self = shift;
    if ( $Rose::DB::Object::VERSION < 0.7712 ) {
        croak "Rose::DB::Object VERSION 0.7712 or later required";
    }
    elsif ( !$self->can('as_tree') ) {
        croak "You must load Rose::DB::Object::Helpers as_tree() method";
    }
    return $self->as_tree( @_, force_load => 1 );
}

sub exists {
    my $self = shift;
    my @arg  = @_;
    if ( !@arg && ref($self) ) {
        for my $col ( $self->meta->column_accessor_method_names ) {
            push( @arg, $col, $self->$col ) if defined( $self->$col );
        }
    }
    my $count = Rose::DB::Object::Manager->get_objects_count(
        object_class => ref($self) || $self,
        query => [@arg]
    );

    return $count if defined($count);
    croak "Error: " . Rose::DB::Object::Manager->error;
}

sub has_related {
    my $self   = shift;
    my $rel    = shift or croak "need Relationship name";
    my $method = $rel . '_count';
    if ( $self->can($method) ) {
        return $self->$method;
    }
    else {
        my $other = $self->$rel;
        if ( ref $other eq 'ARRAY' ) {
            return scalar @$other;
        }
        else {
            return $other ? 1 : 0;
        }
    }
}

sub has_related_pages {
    my $self   = shift;
    my $rel    = shift or croak "need Relationship name";
    my $pgsize = shift or croak "need page_size";
    if ( $pgsize =~ m/\D/ ) {
        croak "page_size must be an integer";
    }
    my $n = $self->has_related($rel);
    return 0 if !$n;
    if ( $n % $pgsize ) {
        return int( $n / $pgsize ) + 1;
    }
    else {
        return $n / $pgsize;
    }
}

sub fetch_all {
    my $self  = shift;
    my $class = $self->meta->class;
    return Rose::DB::Object::Manager->get_objects(
        object_class => $class,
        @_
    );
}

sub fetch_all_iterator {
    my $self  = shift;
    my $class = $self->meta->class;
    return Rose::DB::Object::Manager->get_objects_iterator(
        object_class => $class,
        @_
    );
}

sub column_is_boolean {
    my $self = shift;
    my $col  = shift;
    croak "column_name required" unless defined $col;
    if (    $self->meta->column($col)
        and $self->meta->column($col)->type eq 'boolean' )
    {
        return 1;
    }
    else {
        return 0;
    }
}

1;