EPrints Technical Mailing List Archive

Message: #02517


< Previous (by date) | Next (by date) > | < Previous (in thread) | Next (in thread) > | Messages - Most Recent First | Threads - Most Recent First

[EP-tech] Re: Understanding how data objects link


Hi Ian,

Your problem may come from perl_lib/EPrints/MetaField/Subobject.pm::get_value


my $ds = $parent->get_session->dataset( $self->get_property( "datasetid" ) );

        my $searchexp = $ds->prepare_search();

        if( $ds->base_id eq "document" )
        {
                $searchexp->add_field(
                        $ds->field( "eprintid" ),
                        $parent->id
                );
        }
        elsif( $ds->base_id eq "saved_search" )
        {
                $searchexp->add_field(
                        $ds->field( "userid" ),
                        $parent->id
                );
        }
        # ETC...


(you should upgrade to 3.3 one day ;-))

Seb.


On 15/01/14 09:39, Ian Stuart wrote:
I'm creating new data objects in an EPrints repository (EP3.2 as it
happens) to support a new service within my repo.
The idea is that a "subscriber" can register to receive a number of
"postcards", where each postcard is a list of citations of new records
in a [list of] department[s], emailed to a specified email address.

I have two Objects: a "Subscriber" and a "Postcard", based very heavily
on the "EPrint" and "Document" Data Objects.

The fundamental code for the two objects is listed at the end of the email.

The full code is syntactically correct, and loads into EPrints.

When I use the code, I start with a user_id, and want to get the list of
postcards associated with that user, so I have code thus:

    # Before we do anything - we need to get the subscriber object
    my $subs_ds = $session->get_repository->get_dataset("subscriber");
    my $subscriber;

    { # Localise this search
      my $searchexp = EPrints::Search->new(
        session     => $session,
        dataset     => $subs_ds,
      );
      $searchexp->add_field( $subs_ds->get_field("userid"), $user_id );
      warn $searchexp->render_description->toString;
      my $results = $searchexp->perform_search;

      if ($results->count) {
        my @records = $searchexp->perform_search->slice(0,1); # Get
records from position 0, for a count of 1 records
        $subscriber = $records[0]
      } else {
        $subscriber = EPrints::DataObj::Subscriber->create( $session,
{userid => $user_id }, $subs_ds );
      }
    }

    # Having got a subscriber object, lets get a list of postcards they have
    # Postcards are 1 email address and some number of repositories
    warn "got subscriber " . $subscriber->get_id . "\n";
    my $postcards = $subscriber->get_value( 'postcards' );

This code successfully returns a matching "Subscriber", however the
final line in that code is causing me problems... I get the error

    dataset postcard has no field: datasetid

I have double-checked my code against that of EPrints::DataObj::EPrint
and EPrints::DataObj::Document - neither of them have a datasetid field,
and my own objects are creating records in exactly the same way!

I've a few questions... but mostly I'd like someone to try to explain
how new data-objects should be made, and what's needed.

Oh - and once I've got this working, I *WILL* add documentation to the
Wiki... if nothing else, it'll help me understand what my codes doing,
and why :chuckle:




package EPrints::DataObj::Subscriber;

our @ISA = ('EPrints::DataObj');

use EPrints;

sub get_system_field_info {
    my ($class) = @_;

return (
      { name => "subscriberid", type => "counter",
        required => 1, import => 0, can_clone => 0,
        sql_counter => "subscriberid"
      },
      { name => "userid", type => "text", required => 1 },
      { name => "postcards", type => "subobject",
        datasetid => 'postcard', multiple  => 1
      },
    );
} ## end sub get_system_field_info

sub get_dataset_id {
    return "subscriber";
}

sub get_all_postcards {
    my ($self) = @_;

    return @{ ( $self->get_value("postcards") ) } ;
   } ## end sub get_all_postcards

1;
package EPrints::DataObj::Postcard;

our @ISA = ('EPrints::DataObj::SubObject');

use EPrints;

sub get_system_field_info {
    my ($class) = @_;

    return (
      { name => "cardid", type => "counter",
        required => 1, import => 0, show_in_html => 0,
        can_clone => 0, sql_counter  => "postcardid"
      },
      { name => "email", type => "text", required => 1 },
      { name => "subscriberid", type => "itemref",
        datasetid => "subscriber", required => 1, show_in_html => 0
      },
      { name => "repos", type => "compound", multiple => 1,
        fields => [
          { sub_name => "repoid",   type => "text", },
          { sub_name => "reponame", type => "text", },
        ],
      },
    );

} ## end sub get_system_field_info

sub get_dataset_id {
    return "postcard";
}

sub get_parent {
    my ( $self, $datasetid, $objectid ) = @_;

    $datasetid = "subscriber";
    $objectid  = $self->get_value("subscriberid");

    return $self->SUPER::get_parent( $datasetid, $objectid );
} ## end sub get_parent
1;