I'm making quite a bit of custom rose functions for my projects , and  
looking for feedback on some that i think would be useful if rolled  
back into Rose::DB::Helpers

the newest one is related_index

related_index takes a rose object and creates an internal hash to  
quickly access specific LOADED items based on primary keys ( multiple  
keys are supported using a 'col1:col2' format )

its kind of like the 'find' functionality, except it never goes to  
the database ( its only on loaded items ).   the indexing just stores  
a ref to the object in an internal lookup tree for fast access.

the current code lets you control the depth of recursion to index,  
and subsets of relations to index

example:

        $userObject=  
RoadSound::Rose::Db::Object::Useraccount::Manager::load_user_and_favorit 
e_artists( user_id=> $user_id );
        P_2XLP__RoseDB_Helpers::related_index__do_index( $userObject ,  
recursion=> -1 , index_only=> ['favorite_artists'] );
        if ( my $artist= P_2XLP__RoseDB_Helpers::related_index__get 
($userObject,'favorite_artists',52) )
        {
                print STDERR "\n User likes artist( primary_key 52 )" . 
$artist- 
 >name ;
        }

caveats:
        •       you must manually reindex each item if you reload , update.
                this kind of makes me wish there were some sort of configurable 
 
post load/get_objects hook supported in rose -- though you can create  
a custom manager that wraps those calls with it.
        •       the code does not support 'index only' on recursion


-----

use strict;
package P_2XLP__RoseDB_Helpers;
use Rose::DB::Object::Helpers ();
use base qw(Rose::DB::Object::Helpers);
######################################################################

sub _related_index_namespace { return 'com. 
2xlp::RoseDB_Helpers::related_index' ; };
=pod
                related_index__do_index
                        $self
                        %kw_args
                                index_only ARRAY
                                        list of relationship names to index
                                recursive INTEGER
                                        how many levels deep to recurse
                                        0 - none ( default )
                                        1 ( N > 0 ) - exact amount of levels
                                        -1      - recurse all                   
                                                
                        
                        ToDo:
                                recursive_index_only - array or ArrayOfArrays 
containing  
recursive relations to index
=cut

sub _related_index_namespace { return 'com.2xlp::related_index' ; };
sub related_index__do_index {
        my      ( $self , %kw_args )= @_ ;

        my      @relationships= $self->meta->relationships ;
        if ( defined $kw_args{'index_only'} )
        {
                my      @rel_index_only;
                my      %rel_index_names= map { $_ => 1 } 
@{$kw_args{'index_only'}};
                foreach my $rel ( @relationships )
                {
                        if ( $rel_index_names{ $rel->name } )
                        {
                                push @rel_index_only , $rel ;
                        }
                }
                @relationships= @rel_index_only;
        }

        my      $recursive= defined $kw_args{'recursive'} ? $kw_args 
{'recursive'} : 0 ;
        if      ( $recursive > 0 )
        {
                $recursive-- ;
        }
        
        foreach my $rel ( @relationships )
        {
                my      $rel_name= $rel->name;
                if ( my $objs= $rel->object_has_related_objects($self) )
                {
                        my      %keyed;
                        foreach my $obj ( @$objs )
                        {
                                my      @index_values;
                                foreach my $primary_key_column_name ( 
@{$obj->meta- 
 >primary_key_column_names} )
                                {
                                        my      $accessor= 
$obj->meta->column_accessor_method_name 
( $primary_key_column_name );
                                        push @index_values , $obj->$accessor;   
                                                                
                                }
                                my      $index_formatted= join ':' , 
@index_values ;
                                $keyed{ $index_formatted }= $obj;
                                if ( $recursive  )
                                {
                                        
P_2XLP__RoseDB_Helpers::related_index__do_index( $obj ,  
'recursive'=> $recursive );
                                }
                        }
                        P_2XLP__RoseDB_Helpers::related_index__set( $self , 
$rel_name , \% 
keyed );
                }
        }
}
sub related_index__set {
        my      ( $self , $rel_name , $index_hash_ref )= @_;
        $self->{ P_2XLP__RoseDB_Helpers::_related_index_namespace() } 
{ $rel_name }= $index_hash_ref;
}
sub related_index__get {
        my      ( $self , $rel_name , $primary_key )= @_;
        die "not indexed" unless defined $self-> 
{ P_2XLP__RoseDB_Helpers::_related_index_namespace() }{ $rel_name };
        return $self->{ P_2XLP__RoseDB_Helpers::_related_index_namespace() } 
{ $rel_name }{ $primary_key } || undef ;
}


######################################################################
1;
######################################################################


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object

Reply via email to