/usr/local/CPAN/Sash-Plugin-VerticalResponse/Sash/Plugin/VerticalResponse/Cursor.pm
package Sash::Plugin::VerticalResponse::Cursor;
use strict;
use warnings;
use base qw( Sash::Cursor );
use Carp;
# Apparently I will sell you the rope you are going to use to hang me with...
sub AUTOLOAD {
our $AUTOLOAD;
# No really what this does is allow sash to grow as the api grows and uses
# the same type of data structures.
if ( $AUTOLOAD =~ /::(\w*)\_meth$/ ) {
my $self = shift;
my $method = $1;
# Just in case you didn't grok it, $1 is the name of the method from
# the match above.
my $result = $self->{client}->$method( $self->query );
# Account for the fact that create methods just return the
# id of the record.
$result = { id => $result } if $method =~ /^create/;
# In the delete methods case the query is a hash so we want the
# return value to be the record id that was passed to us.
$result = { id => ( %{$self->query} )[1] } if $method =~ /^delete/;
$self->_define_header_data( $result );
return;
}
}
sub open {
my $class = shift;
my $args = shift;
# We have a usage relationship with this singleton.
$args->{client} = Sash::Plugin::VerticalResponse->client;
my $self = $class->SUPER::open( $args );
return $self;
}
sub _define_header_data {
my $self = shift;
my $result = shift;
my $attributes = shift;
my $header;
my $data;
# Help format VR Special Datatypes for simple output.
my $format_data_attribute = sub {
my $attribute = shift;
my $joinby = ( Sash::Properties->output eq Sash::Properties->vertical ) ? "\n" : ', ';
if ( ref $attribute eq 'ArrayOfString' ) {
return undef unless scalar( @$attribute ) > 0;
return join $joinby, @$attribute;
}
return $attribute;
};
# The real purpose of this method is to convert what otherwise would be nested
# data into data that is at the same level so to speak for each attribute in
# the nested structure.
my $expand_record = sub {
my $record = shift;
my $expanded_record = { };
my $header;
foreach my $attribute ( sort keys %$record ) {
if ( ref $record->{$attribute} eq 'NVDictionary' ) {
$expanded_record = { %$expanded_record, map { $_->{name} => $_->{value} } @{$record->{$attribute}} };
} elsif ( ref $record->{$attribute} eq 'StreetAddress' ) {
$expanded_record = { %$expanded_record, map { $_ => $record->{$attribute}->{$_} } sort keys %{$record->{$attribute}} };
} else {
$expanded_record->{$attribute} = $record->{$attribute};
}
}
return $expanded_record;
};
my $use_result = $result;
$use_result = [ $use_result ] unless uc( ref $use_result ) =~ /^ARRAY/;
$data = [
map {
my $record = $expand_record->( $_ );
$header = [ sort keys %$record ] unless defined $header;
[ map { $format_data_attribute->( $record->{$_} ) } sort keys %$record ];
} @$use_result
];
$self->result( $result );
$self->header( $header );
$self->data( $data );
return;
}
sub getCompany_meth {
my $self = shift;
my $company = [ $self->{client}->getCompany( $self->query ) ];
my @users;
if ( defined $company->[0]->{users} ) {
@users = $company->{users};
delete $company->{users};
my @user_ids = map { $_->{id} } @users;
$company->{user_ids} = @user_ids;
}
$self->_define_header_data( $company );
return;
}
sub show_proc {
my $self = shift;
my $header = [ 'Methods' ];
my $data = [ map { [ $_ ] } sort $self->{client}->_methods ];
$self->header( $header );
$self->data( $data );
return;
}
1;