DBIx-Class-Indexer-WebService-Dezi

 view release on metacpan or  search on metacpan

lib/DBIx/Class/Indexer/WebService/Dezi.pm  view on Meta::CPAN

that will be indexed by the dezi service.

=cut

sub as_document {
    my ( $self, $object ) = @_;

    my $fields = $object->index_fields;

    my %output;
    # for each field in schema...
    for my $name ( keys %$fields ) {
        my $opts    = $fields->{$name};
        my @values  = $self->value_for_field( $object, $name );

        if ( defined $opts->{is_binary} ) {
            my $file_path    = $values[0];

            my $content_type = $self->_determine_content_type($file_path);
            my $binary_data  = $self->_read_binary($file_path);

            @values = ($content_type, $binary_data);

            if ( defined $opts->{base64_encode} ) {
                @values = ($content_type, encode_base64($binary_data));
            } else {
                @values = ($content_type, $binary_data);
            }

        }
    
        for( @values ) {
            $output{$name} = [ @values ]
        }
    }

    my $output_str = $self->_generate_document(\%output);

    return \$output_str;
}

=head2 BUILD( $self )

Creates a new Dezi::Client object and normalizes the fields to be
indexed.

=cut
sub BUILD {
    my ( $self ) = @_;
    $self->setup_fields( $self->source );
    return $self;
}


=head2 update_or_create_document( $object )

Handles the insert operation.

=cut

sub update_or_create_document {
    my $self   = shift;
    my $object = shift;

    $self->setup_fields( ref $object );
    $self->_dezi->index( $self->as_document( $object ), $object->id, $self->content_type );

}


=head2 value_for_field( $object, $key )

Uses the indexed fields information to determine how to get
the values for C<$key> out of C<$object>. 

The logic here was borrowed from DBIx::Class::Indexer::WebService::Solr

=cut

sub value_for_field {
    my( $self, $object, $key ) = @_;
    my $info   = $object->index_fields->{ $key };
    my $source = $info->{ source } || $key;

    if( ref $source eq 'CODE' ) {
        return $source->( $object );
    }
    elsif( not ref $source ) {
        my @accessors = split /\./, $source;
        
        # no use calling 'me' on myself...
        shift @accessors if lc $accessors[ 0 ] eq 'me';
        
        # traverse accessors
        my @values = $object;
        for my $accessor ( @accessors ) {
            @values = grep { defined }
                 map  {
                       Scalar::Util::blessed( $_ ) and $_->can( $accessor ) ? $_->$accessor
                     : ref $_ eq 'HASH' ? $_->{ $accessor }
                     : undef
                 } @values;
        }
        return wantarray ? @values : $values[ 0 ];
    }
}

=head2 setup_fields( $source )

Normalizes the index fields so they all have hashref members with an optional
boost key.

=cut
sub setup_fields {
    my( $self, $source ) = @_;

    return if $self->get_field_prep( $source );

    my $fields = $source->index_fields;
  
    # normalize field defs
    for my $key ( keys %$fields ) {
        $fields->{ $key } = { } if !ref $fields->{ $key };
    }

    $self->set_field_prep( $source => 1 );
}

=head2 delete( $object )

Handles the delete operation.

=cut

sub delete {
    my $self   = shift;
    my $object = shift;

    $self->setup_fields( ref $object );

    my $id = $self->value_for_field( $object, 'id' );
    $self->_dezi->delete( $id );  
}

=head2 insert( $object )

Handles the insert operation.

=cut

sub insert {
    my $self   = shift;
    my $object = shift;
    return if $self->disabled;
    $self->update_or_create_document( $object );
}

=head2 update( $object )

Handles the update operation.

=cut

sub update {
    my $self   = shift;
    my $object = shift;
    return if $self->disabled;
    
    $self->update_or_create_document( $object );
}

sub _determine_content_type {
    my ( $self, $file_path ) = @_;
    my ($ext)   = $file_path =~ /\.([^\.]+)$/g;
    my $type    = type_from_ext($ext);
    return $type;
}

sub _read_binary {
    my ( $self, $file_path ) = @_;
    my $bin_data = read_file( $file_path, binmode => ':raw' ) ;
    return $bin_data;
}

sub _generate_document {
    my ( $self, $fields ) = @_;

    my $output_str;
    if ( $self->content_type eq 'application/xml' ) {
        require XML::Simple;
        my $xs = XML::Simple->new;
        $output_str = $xs->XMLout($fields, NoAttr => 1, RootName=>'doc',);
    } elsif ( $self->content_type eq 'application/json' ) {
        require JSON;
        $output_str = JSON::encode_json({ doc => $fields });
    }

    return $output_str;
}

__PACKAGE__->meta->make_immutable;

=head1 AUTHOR

Logan Bell, C<< <loganbell at gmail.com> >>

=head1 BUGS

Please report any bugs or feature requests to C<bug-dbix-class-indexer-webservice-dezi at rt.cpan.org>, or through
the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=DBIx-Class-Indexer-WebService-Dezi>.  I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.

=head1 SUPPORT

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

    perldoc DBIx::Class::Indexer::WebService::Dezi


You can also look for information at:

=over 4

=item * RT: CPAN's request tracker (report bugs here)



( run in 0.405 second using v1.01-cache-2.11-cpan-39bf76dae61 )