The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Perlbug::Object - Object handler for Perlbug database

DESCRIPTION

Handles Perlbug database objects, typically bug, group, message, patch, note, test, user, and severity, status etc....

Methods included to recognise objects by their id or by their also unique name.

SYNOPSIS

        my $o_obj       = Perlbug::Object->new(\%init); # see L<new()>

        $o_obj          = $o_obj->read($oid);           # data

        my $name        = $o_obj->data('name');         # Bug

        # ALL bugids (optionally) constrained by sql 'where' clause
        my @ids         = $o_obj->ids($where);  # where

        # Relation ids
        my @patchids    = $o_obj->rel_ids('patch');     # relids 

        print = $o_obj->format('h');            

METHODS

new

Create a new object, you need to supply up to three (3) things:

        1. A pre-initialised Perlbug::Base->new() object:

        2. Attribute pairs: 

        3. Relation array refs:

                b<float> is a straight column related to our id and has no distinct object handler, 

                b<from> and B<to> are related with full ids, handlers, etc. treatment.

Example:

        my $o_obj = Perlbug::Object->new( 
                # Optional base object, useful to maintain transactions
                        $o_Perlbug_Base_Object,         # 
                # Attributes
                        'name'  => 'Bug',               # mandatory key 
                # Relationships 
                        'float' => [qw(change)],                        
                        'from'  => [],
                        'to'    => [qw(message note patch test user)], 
        };
init_data

Initialise generic object attr, columns and column_types from table in db (specific).

        my $o_obj = $o_obj->init_data($table);
init_types

Initialise generic object attr based on table from db, returns relation names.

        my @rels = $o_obj->init_types(@rel_types);
reinit

Reset object to default values, with optional object_id where different, returns object

        $o_obj->reinit($oid);

To check whether the object was succesfully reinit, ask:

        my $i_isok = $o_obj->REINIT; # ?
refresh_relations

Refresh relation data, optionally restricted to only those given, others are cleared.

        $self->refresh_relations([\@wanted]);
check

Check all attr are initialised

        my $i_ok = $o_obj->check(\%attributes);
REINIT

Returns 0|1 depending on whether object has been reinit

        my $i_isok = $o_obj->REINIT;
exists

Examines the database to see if current object exists already.

Second optional parameter overrides sql caching

Return @ids

        print "yup\n" if $o_obj->exists([$oid]);
_exists

Examines the database to see if current object exists by identifier already.

Second optional parameter overrides sql caching

        print "yup\n" if $o_obj->_exists(\@ids);
data_fields

Returns all valid data field names for this object

        my @fields = $o_obj->data_fields;
str2ids

Return appropriate (match_oid)s found in given string

        my @ids = $o_obj->str2ids($str);
ok_ids

Checks to see if given oid/s look anything like we are expecting them to.

Returns list of acceptable object ids

        my @ok_ids = $o_obj->ok_ids(\@some_ids);
primary_key

Wrapper to only get primary_key.

        my $pri = $o_obj->primary_key;
key

Wrapper to get and set key.

        my $key = $o_obj->key($key);
objectid

Wrapper to get and set objectid, (and data(<objectid>) at the same time.

        my $oid = $o_obj->objectid($id);
ids

Gets DISTINCT ids, for this object

        my @all_ids  = $o_obj->ids(); 

Which is a bit like an unrestricted col($primary_key, '') call.

More useful are the following examples, restrained by object, or sql WHERE statement:

        my @rel_ids  = $o_obj->ids($o_rel, [$further_restrained_by_sql], 'refresh');

        my @selected = $o_obj->ids($where);
names

Get DISTINCT names for this object.

If there is no ident=name, or no names, for the object, returns empty list().

For restraints/parameters see ids()

        my @names = $o_obj->names();
col

Gets DISTINCT column, from all or with a where sql statement

        my @all_cols = $o_obj->cols('name');

        my @rel_cols = $o_obj->cols('name, $o_rel);

        my @selected = $o_obj->cols('name', $where);
identifier

Return identifying string key for this object, 'name' or whatever

id2name

Convert ids to names

        my @names = $o_obj->id2name(\@ids);
name2id

Convert names to ids

        my @ids = $o_obj->name2id(\@names);
count

Return number of objects, optionally restrained by argument given

        my $i_cnt = $o_obj->count;

        my $i_cnt = $o_obj->count($o_rel); # uses o_rel(objectid) 

        my $i_cnt = $o_obj->count("$objectid LIKE '$criteria'");
trim

Return args trimmed of whitespace, ready for comparison checks

        my @trimmed = $o_obj->trim([qw(this and that)]);
keys_sorted_by_value

Return list of keys sorted by values

        my @sorted = $o_obj->keys_sorted_by_value(\%hash);
choice

Returns appropriate popup() or selector() for object, based on prejudicial setting.

        print $o_obj->choice($unique_name, [$selected]); # or none('') 

Create scrolling web list popup with given pre-selection (or any), with (alphabetically sorted) names where possible

        my $popup = $o_obj->popup('unique_name', $selected); # or none('') 
selector

Create scrolling web list selector with given pre-selections, with names where possible. Also appends simple list of selected items.

        my $selctr = $o_obj->selector('unique_name', \@pre_selected);
text_area

Create text_area with given args, prep for select(js)

        my $ta = $o_obj->text_area('unique_name', 'value', [etc.]);
text_field

Create text_field with given args, prep for select(js)

        my $tf = $o_obj->text_field('unique_name', 'value', [etc.]);
_gen_field_handler

Generate code to handle get and set object fields, returns 1|0

        my $i_ok = $o_obj->_gen_field_handler('header');

        my $var = $o_obj->header($msg); # var has msg
base

Return application specific Perlbug::Base object, given as $o_obj->new($o_base) or new object altogether.

RELATIONS

Object relations are handled by a group of methods:

        my @rellies     = $o_obj->relations('to');      # patch, message, note, test, user, 

        my $o_patch     = $o_obj->relation('patch');    # handler

        my @pids        = $o_patch->ids($o_obj);        # or

        my @pids        = $o_obj->relation_ids('patch');# ids

Note that relations are between one object and (from or to) another, or of a 'floating' kind.

If it's another object you want, see "object()".

relation_types

Return relation types for current object

        my @types = $self->relation_types; # from, to
isarel

Returns 1|0 dependant on whether relation($rel), is of given type (or any), or not

        print "yup\n" if $o_obj->isarel($rel);

eg:

        print "patch is related to a bug\n" if $o_pat->isarel('bug');

        print "patch is related to a bug\n" if $o_pat->isarel('bug');
relations

Return relations, filtered by arg, or all if none given

        my @rellies = $self->relations('from'); # patch, user, etc.
relation

Return object handler for given relation

        my $o_b2p = $o_bug->relation('patch');

        print $o_b2p->assign(\@list_new_patch_ids_2_bug);

If the original (in this case bug) object had already an oid() assigned, (it knew which bug it represented), the relation will be pre-initialised with the relevant bugid, by for example a read() call. Note, however, that where the sourceid is unknown, then only a generic relationship object is returned. eg; this should explicitly work:

        print $o_bug->read('19870502.007')->relation('patch')->assign(\@pids);

Note that the read() method takes a single liberty, in that it calls Perlbug::Relation::set_source() on the retrieved relation, thus ensuring said relation knows which object, (of the two that it holds) to regard as source.

See Perlbug::Relation for more info on relation methods.

relation_ids

Return relation IDs for given object

        my @patch_ids = $o_obj->relation_ids('patch');
_rel_ids

Refresh rel_ids

relation_names

Return relation names for given object, or empty list() if no names, or not ident=name

        my @os_names = $o_obj->relation_names('osname');
relate

Work through the given hash using the objects' relations():

        B<assign()>ing any relation-ids found

        B<_assign()>ing any relation-names found

Prejudicial against $o_rel->attr('prejudicial') relationships, and is designed to take the output of Perlbug::Base::parse_str().

Returns name of objects assigned to.

        my $i_rels = my @rels = $o_obj->relate(\%relationships);

        where B<%relationships> = (
                'address'       => {
                        'ids'   => [qw(7 223 78 26 13)],
                },
                'address'       => {
                        'names' => [qw(me@home.net buggy@system.com etc@the.net)],
                },
                'bug'           => {
                        'ids'   => [qw(19870502.007)],
                },
                'group'         => {
                        'ids'   => [qw()],
                },
                'osname'        => {
                        'ids'   => [qw(3 7 21 23)],
                        'names'         => [qw(aix irix macos win32)],
                },
                'status'        => {
                        'names' => [qw(open)],  
                },
                'version'       => {
                        'ids'   => [qw(4 28 273)],
                        'names' => [qw(5.7.3)],
                },
        ); 

See also rtrack()

appropriate

Attempts to relate relatable bug relations to relevant bugs :-)

The idea is that a test can call appropriate() after a relate(), and this will apply appropriate status flags to any bugids found, etc.

See "relate()" for more info.

        my @bugids = $o_obj->appropriate(\%rels);

RECORDS

Record handling methods for Perlbug::Object::\w+'s

read

Read the data, from the db, by id, and load into current object.

After this it is possible to get to meaningful relations via rel_ids(), and correct format()ing

Returns object so it is possible to chain calls.

        $o_obj->read($id);

And...

        print $o_obj->read($id)->format('h'); # etc.

To check whether the object was succesfully read, ask:

        my $i_isok = $o_obj->READ; 
READ

Returns 0|1 depending on whether object has had a successful read, post new/init/reinit

        my $i_isok = $o_obj->READ;
_read

Wrap read() call to operate by name (if possible)

        print $o_obj->_read($name)->format('h'); # etc.
column_type

Return sql type for given column name

        my $datetime = $o_obj->column_type('created'); # DATETIME

        my $integer  = $o_obj->column_type('created'); # INTEGER 

        my $varchar  = $o_obj->column_type('created'); # VARCHAR <default>
to_date

Currently redundant, because Mysql takes care of this, but Oracle may want to do more than this...

        my $sql_date = $o_obj->to_date($date_string);
prep

Quote (or not) given data, ready to go into our table

        my $sql = $o_obj->prep('insert', $h_data); # or 'update'
create

Creates a new system object via inserting the given data into the db, loaded from current object, or given data.

Returns $o_object->read($id).

        $o_obj->create();               # using object data

        $o_obj->create($h_data);        # using given data, note B<only> this data is used!

        $o_obj->create($h_data, 'relation');    # ignore exists call

N.B. caller must set up the appropriate objectid (\d+|<bugid>|NULL|Sequence|...) previously.

To check whether the object was succesfully created, ask:

        my $i_isok = $o_obj->CREATED; #
CREATED

Returns 0|1 depending on whether object has been succesfully created

        my $i_isok = $o_obj->CREATED;
store

Stores the given data into the db, (creates new data record), loaded from current object, or given data.

Executes an insert() or update() dependent on whether the object pre-exists or not.

For more info see create() and update().

Returns $o_object->read($id).

        $o_obj->store();                # using object data

        $o_obj->store($h_data); # using given data, note B<only> this data is used!

To check whether the object was succesfully stored, ask:

        my $i_isok = $o_obj->STORED; # ?
STORED

Returns 0|1 depending on whether object has been succesfully stored

        my $i_isok = $o_obj->STORED;
update

Update the given data into the db, loaded from current object, or given data.

        $o_obj->update();                       # using object data

        $o_obj->update($h_data);        # using given data, note B<only> this data is used!

To check whether the object was succesfully updated, ask:

        my $i_isok = $o_obj->UPDATED; # ?
UPDATED

Returns 0|1 depending on whether object has been succesfully updated

        my $i_isok = $o_obj->UPDATED;
delete

Delete the given objectid/s or current object, and all it's relationships

        $o_obj->delete();                               # this object

        $o_obj->delete(\@oids);                 # list ref

To check whether the object/s was succesfully deleted, ask:

        my $i_isok = $o_obj->DELETED; # 0|1
DELETED

Returns 0|1 depending on whether object has been succesfully deleted

        my $i_isok = $o_obj->DELETED;
updatable

Check if current object(type) is allowed to be updated

Returns updatable ids

    print 'updatable: '.join(', ', $o_obj->updatable(\@ids));
insertid

Returns newly inserted id from database statement handle

        my $new_oid = $o_obj->insertid($sth, $oid);
new_id

Return valid new object id for given object, usually NULL, as Mysql generates own.

        my $new_oid = $o_obj->new_id

        # Bug expected to generate it's own
        # Mysql specific
        # Oracle requires SELECT FROM SEQUENCE ...
        # Relations map differently...

CONVENIENCE

Convenient wrappers for the following methods are supported, for more details see Perlbug::Base

error

Wrapper for $o_obj->base->error()

debug

Wrapper for $o_obj->base->method()

object

Wrapper for $o_obj->base->method()

format

Simple wrapper for FORMAT()

        my $str = $o_obj->format('h');
template

Applies appropriate template to this object, based on optional format.

        my $str = $o_obj->template($fmt); # [ahl...]
diff

Returns differences between two (format|templat)ed strings, on a per line basis.

Note that multiple blank lines are reduced to a single blank line.

        my $diff = $o_obj->diff("this\nand\that", "this\nor\nthat\netc.");

Produces:

        old:
                2  and
                4

        new:
                2  or
                4  etc.
rtrack

Tracks object administration (relations), where %entry is the relevant relate() data, etc.

        $o_obj = $o_obj->rtrack(\%data, [$obj, [$objectid]]);
TRACKED

Returns 0|1 depending on whether object has been succesfully TRACKED

        my $i_isok = $o_obj->TRACKED;
attr

Get and set attributes

        my $objectid = $o_obj->attr('objectid');                        # get

        my $newobjid = $o_obj->attr({'objectid', $newid});      # set
data

Get and set data by hash ref.

Returns data values, all if none specified.

        $o_obj->data({
                'this'  => 'that',
                'and'   => 'so on',
        });

        my $name = $o_obj->data('name');

        my @vals = $o_obj->data;
flag

Get and set flags

        my $i_read = $o_obj->flag('read');                      # get
attr
data
flag

Note that to set any of these you have to send in a hashref!

Returns keys of succesful updates

        my $attr = $self->attr('objectid');                     # get

        my @keys = $self->data();                                               # get

        my $data = $self->flag({'created' => 1});               # set $data=created

        my @data = $self->data({'name' => 'newname', 'body'     => 'stuff'}); # set 

AUTHOR

Richard Foley perlbug@rfi.net 2000 2001