cvsuser     02/01/30 11:48:13

  Modified:    P5EEx/Blue/P5EEx/Blue Repository.pm
  Log:
  reorder methods within the file for clearer POD output
  
  Revision  Changes    Path
  1.7       +597 -545  p5ee/P5EEx/Blue/P5EEx/Blue/Repository.pm
  
  Index: Repository.pm
  ===================================================================
  RCS file: /cvs/public/p5ee/P5EEx/Blue/P5EEx/Blue/Repository.pm,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -w -r1.6 -r1.7
  --- Repository.pm     24 Jan 2002 04:15:07 -0000      1.6
  +++ Repository.pm     30 Jan 2002 19:48:13 -0000      1.7
  @@ -1,6 +1,6 @@
   
   #############################################################################
  -## $Id: Repository.pm,v 1.6 2002/01/24 04:15:07 spadkins Exp $
  +## $Id: Repository.pm,v 1.7 2002/01/30 19:48:13 spadkins Exp $
   #############################################################################
   
   package P5EEx::Blue::Repository;
  @@ -122,6 +122,53 @@
   A Repository is a means by which data may be stored somewhere without
   knowing what underlying technology is storing the data.
   
  +A Repository is the central persistence concept within the P5EE.
  +A Repository does not present a uniquely object-oriented view of
  +its data.  Rather it presents a "logical relational" data model.
  +It does not return objects, but rows of data.
  +
  +The "logical data model" means that a developer can program to
  +the data model which usually comes out of system requirements analysis,
  +closely modelling the business.  All of the changes to this
  +logical data model that are
  +incorporated during physical database design are abstracted
  +away, such as:
  +
  +  * physical table naming,
  +  * physical column naming,
  +  * normalization of data into parent tables, and
  +  * splitting of tables based on various physical constraints.
  +
  +This could be called object-to-relational mapping, but it is more
  +accurately called logical-to-physical-relational mapping.
  +
  +Despite the fact that the Repository is a relational data storage
  +abstraction, persistent objects (i.e. Entity Widgets) can be built to
  +save and restore their state from a Repository.  Furthermore, the
  +built-in support for non-scalar fields (references to arbitrarily
  +complex perl data structures) and the ability for Entity Widgets
  +to encapsulate more than one row of data, makes the technology quite
  +fit for object-oriented development.
  +
  +The design of the Repository is based around three important uses of
  +data.
  +
  +  * Transaction Processing
  +  * Batch Processing
  +  * Report Generation
  +
  +(more about this later)
  +
  +The Repository abstraction seeks to solve the following problems.
  +
  +  * objects may have attributes that come from multiple sources
  +  * caching
  +  * isolated from physical database changes
  +  * transactions
  +  * data source independence
  +  * no save/restore
  +  * devel/test/prod environments
  +
   =cut
   
   #############################################################################
  @@ -136,11 +183,11 @@
   
   =item * Class: P5EEx::Blue::Repository
   
  -=item * Class: P5EEx::Blue::Repository::BerkeleyDB
  +=item * Class: P5EEx::Blue::Repository::DBI
   
   =item * Class: P5EEx::Blue::Repository::File
   
  -=item * Class: P5EEx::Blue::Repository::DBI
  +=item * Class: P5EEx::Blue::Repository::BerkeleyDB
   
   =item * Class: P5EEx::Blue::Repository::LDAP
   
  @@ -150,6 +197,15 @@
   =item * Class: P5EEx::Blue::Repository::SOAP
         - remote data storage
   
  +=item * Class: P5EEx::Blue::Repository::Cache
  +      - use the Cache::Cache module
  +
  +=item * Class: P5EEx::Blue::Repository::SPOPS
  +      - maybe?
  +
  +=item * Class: P5EEx::Blue::Repository::Tangram
  +      - maybe?
  +
   =back
   
   =cut
  @@ -233,99 +289,6 @@
   
   =cut
   
  -#####################################################################
  -# init()
  -#####################################################################
  -
  -=head2 init()
  -
  -    * Signature: $repository->init();
  -    * Signature: $repository->init($named);
  -    * Param:     deferConnection     integer
  -    * Return:    void
  -    * Throws:    P5EEx::Blue::Exception::Repository
  -    * Since:     0.01
  -
  -    Sample Usage: 
  -
  -    $self->init();
  -
  -Initialize the {config} structure and the {name} attribute.
  -
  -Every Service constructor (Repository is derived from Service) will
  -invoke the init() method near the end of Repository object construction.
  -
  -The standard behavior (implemented here) in init() is to initialize
  -variables of the Repository, call init2(), connect to the repository,
  -and load the repository metadata.
  -
  -=cut
  -
  -sub init {
  -    my ($self, $args) = @_;
  -    my ($dbidriver, $dbname, $dbuser, $dbpass, $dbioptions, $dbschema);
  -    my ($name, $config);
  -
  -    $self->{numrows} = 0;
  -    $self->{error}   = "";
  -
  -    $self->init2($args);
  -
  -    if (!$self->{config}{deferConnection} && !$self->connect()) {
  -        my ($config);
  -        $config = $self->{config};
  -
  -        print STDERR "Error on connect():";
  -        foreach (keys %$config) {
  -            print STDERR " $_=[", $config->{$_}, "]";
  -        }
  -        print STDERR "\n";
  -        return(undef);
  -    }
  -
  -    $self->load_rep_metadata();
  -}
  -
  -#############################################################################
  -# init2()
  -#############################################################################
  -
  -=head2 init2()
  -
  -    * Signature: $repository->init2();
  -    * Signature: $repository->init2($named);
  -    * Param:     deferConnection    integer
  -    * Return:    void
  -    * Throws:    P5EEx::Blue::Exception::Repository
  -    * Since:     0.01
  -
  -    Sample Usage: 
  -
  -    $self->init2();
  -
  -The default behavior of init2() is defined here in the Repository class
  -and is intended to be overridden (if necessary) in the subclass which
  -implements the details of access to the physical data store.
  -
  -This default behavior is simply to copy the values in the configuration
  -into the attributes of the object itself. i.e.
  -
  -    $self->{$var} = $self->{config}{$var};
  -
  -=cut
  -
  -sub init2 {    # OVERRIDE IN SUBCLASS TO GET NON-DEFAULT CAPABILITIES
  -    my $self = shift;
  -
  -    my ($config, $var);
  -    $config = $self->{config};
  -    if (defined $config) {
  -        foreach $var (keys %$config) {
  -            $self->{$var} = $config->{$var};
  -        }
  -    }
  -}
  -
   #############################################################################
   # PUBLIC METHODS
   #############################################################################
  @@ -577,421 +540,156 @@
   =cut
   
   #############################################################################
  -# load_rep_metadata()
  +# get_type_names()
   #############################################################################
   
  -=head2 load_rep_metadata()
  +=head2 get_type_names()
   
  -    * Signature: $repository->load_rep_metadata();
  +    * Signature: $typenames = $repository->get_type_names();
       * Param:     void
  -    * Return:    void
  +    * Return:    $typenames         []
       * Throws:    P5EEx::Blue::Exception::Repository
       * Since:     0.01
   
       Sample Usage: 
   
  -    $self->load_rep_metadata();
  -
  -Initializes the repository metadata information from the {config}.
  +    $typenames = $rep->get_type_names();
  +    print join(",", @$typenames), "\n";
   
  -    * List of tables (+ displayable labels)
  -    * List of column types (+ displayable labels)
  +Returns the standard set of type names for columns in a repository.
  +These are perl-friendly type names which are useful to do data validation.
   
  -Then it calls load_rep_metadata_auto() in order for the repository
  -itself to be consulted for its metadata information.
  +    * string
  +    * text
  +    * integer
  +    * float
  +    * date
  +    * time
  +    * datetime
  +    * binary
   
   =cut
   
  -# load metadata about TYPES supported by the repository
  -# and the list of TABLES in it.
  -sub load_rep_metadata {
  +sub get_type_names {
       my ($self) = @_;
  +    $self->{types};
  +}
   
  -    my ($repconfig, $table, $tables, $table_defs, $table_def, $native_table, $idx);
  -    $repconfig = $self->{repconfig};
  +#############################################################################
  +# get_type_labels()
  +#############################################################################
   
  -    # start with the list of tables that was configured (or the empty list)
  -    $tables = $repconfig->{tables};
  -    $tables = [] if (!defined $tables);
  -    $self->{tables} = $tables;
  +=head2 get_type_labels()
   
  -    # start with the hash of tables defined (or the empty hash)
  -    $table_defs = $repconfig->{table};
  -    $table_defs = {} if (!defined $table_defs);
  -    $self->{table} = $table_defs;
  +    * Signature: $typelabels = $repository->get_type_labels();
  +    * Param:     void
  +    * Return:    $typelabels        {}
  +    * Throws:    P5EEx::Blue::Exception::Repository
  +    * Since:     0.01
   
  -    # for each table named in the configuration, give it a number up front
  -    for ($idx = 0; $idx <= $#$tables; $idx++) {
  -        $table = $tables->[$idx];
  -        $table_defs->{$table}{idx} = $idx;
  +    Sample Usage: 
  +
  +    $typelabels = $rep->get_type_labels();
  +    foreach (sort keys %$typelabels) {
  +        print "$_ => $typelabels->{$_}\n";
       }
   
  -    # for each table in the hash (random order), add them to the end
  -    foreach $table (keys %$table_defs) {
  -        $table_def = $table_defs->{$table};
  -        $table_def->{name} = $table;
  -        $table_def->{label} = $table if (! $table_def->{label});
  +Returns a hash of all of the repository types and the labels
  +which should be used when displaying them to the user through
  +the user interface.
    
  -        # table has not been added to the list and it's not explicitly "hidden", so 
add it
  -        if (!defined $table_def->{idx} && ! $table_def->{hide}) {
  -            push(@$tables, $table);
  -            $table_def->{idx} = $#$tables;
  +    * string   => "Characters"
  +    * text     => "Paragraph"
  +    * integer  => "Integer"
  +    * float    => "Number"
  +    * date     => "Date"
  +    * time     => "Time"
  +    * datetime => "Date and Time"
  +    * binary   => "Binary Data"
   
  -            # we're not hiding physical tables and a native table was defined, so 
make an entry
  -            if (! $self->{hide_physical}) {
  -                $native_table = $table_def->{native_table};
  -                if (defined $native_table) {
  -                    $table_defs->{$native_table} = $table_defs->{$table};
  -                }
  -            }
  -        }
  +=cut
   
  -        $self->{table_labels}{$table} = $table_def->{label};
  +sub get_type_labels {
  +    my ($self) = @_;
  +    $self->{type_labels};
       }
   
  -    my ($type, $types, $type_defs);
  +#############################################################################
  +# get_type_def()
  +#############################################################################
   
  -    # start with the hash of types defined (or the empty hash)
  -    $type_defs = $repconfig->{type};
  -    $type_defs = {} if (!defined $type_defs);
  -    $self->{type} = $type_defs;
  +=head2 get_type_def()
   
  -    # define the standard list of Repository types
  -    $types = [ "string", "text", "integer", "float", "date", "time", "datetime", 
"binary" ];
  -    $self->{types} = $types;
  +    * Signature: $typedef = $rep->get_type_def($typename);
  +    * Param:     $typename          string
  +    * Return:    $typedef           {}
  +    * Throws:    P5EEx::Blue::Exception::Repository
  +    * Since:     0.01
   
  -    # define the standard list of Repository labels
  -    $self->{type_labels} = {
  -        "string"   => "Characters",
  -        "text"     => "Paragraph",
  -        "integer"  => "Integer",
  -        "float"    => "Number",
  -        "date"     => "Date",
  -        "time"     => "Time",
  -        "datetime" => "Date and Time",
  -        "binary"   => "Binary Data",
  -    };
  +    Sample Usage: 
   
  -    # figure the index in the array of each type
  -    for ($idx = 0; $idx <= $#$types; $idx++) {
  -        $type = $types->[$idx];
  -        $self->{type}{$type}{idx} = $idx;
  -    }
  +    $typedef = $rep->get_type_def("string");
  +    print "$typedef->{name} $typedef->{label}\n";
   
  -    # load up all additional information from the native metadata
  -    $self->load_rep_metadata_auto();
  +Gets a reference to a "type definition", which allows you to access all
  +of the attributes of the requested type
  +(currently only "name" and "label").
  +
  +=cut
  +
  +sub get_type_def {
  +    my ($self, $type) = @_;
  +    $self->{type}{$type};
   }
   
   #############################################################################
  -# load_rep_metadata_auto()
  +# get_table_names()
   #############################################################################
   
  -=head2 load_rep_metadata_auto()
  +=head2 get_table_names()
   
  -    * Signature: $repository->load_rep_metadata_auto();
  +    * Signature: $tablenames = $rep->get_table_names();
       * Param:     void
  -    * Return:    void
  +    * Return:    $tablenames        []
       * Throws:    P5EEx::Blue::Exception::Repository
       * Since:     0.01
   
       Sample Usage: 
   
  -    $repository->load_rep_metadata_auto();
  -
  -Loads repository metadata from the repository itself
  -(to complement metadata in the configuration and perhaps
  -override it).
  +    $tablenames = $rep->get_table_names();
  +    print join(",", @$tablenames), "\n";
   
  -The default implementation does nothing.
  -It is intended to be overridden in the subclass
  -(if the repository has any sort of metadata).
  +Returns the set of table names in the repository.
   
   =cut
   
  -sub load_rep_metadata_auto {     # OVERRIDE IN SUBCLASS (IF DESIRED)
  +sub get_table_names {
       my ($self) = @_;
  +    $self->{tables};
   }
   
   #############################################################################
  -# load_table_metadata()
  +# get_table_labels()
   #############################################################################
   
  -=head2 load_table_metadata()
  +=head2 get_table_labels()
   
  -    * Signature: $self->load_table_metadata();
  +    * Signature: $tablelabels = $rep->get_table_labels();
       * Param:     void
  -    * Return:    void
  +    * Return:    $tablelabels       {}
       * Throws:    P5EEx::Blue::Exception::Repository
       * Since:     0.01
   
       Sample Usage: 
   
  -    $self->load_table_metadata();
  +    $tablelabels = $rep->get_table_labels();
  +    foreach (sort keys %$tablelabels) {
  +        print "$_ => $tablelabels->{$_}\n";
  +    }
   
  -First it calls load_table_metadata_auto() in order for the repository
  -itself to be consulted for any metadata information for the about the
  -table.
  -
  -Then it initializes
  -the repository metadata information for that table from the {config}
  -information.
  -
  -    * List of columns (+ displayable labels, types)
  -    * List of column types (+ displayable labels)
  -
  -Then it determines the set of required columns whenever selecting
  -data from the table and clears the cache of selected rows
  -for the table.
  -
  -=cut
  -
  -# load detailed metadata about a particular table, including
  -# the details about each column
  -sub load_table_metadata {
  -    my ($self, $table) = @_;
  -
  -    # if it's already been loaded, don't do it again
  -    return if (defined $self->{table}{$table}{loaded});
  -    $self->{table}{$table}{loaded} = 1;   # mark it as having been loaded
  -
  -    my ($table_def, $columns, $column, $column_def, $idx, $native_column);
  -
  -    $table_def = $self->{table}{$table};
  -    return if (!defined $table_def);
  -
  -    $columns = $table_def->{columns};
  -    if (! defined $columns) {
  -        $columns = [];
  -        $table_def->{columns} = $columns;
  -    }
  -
  -    # for each column named in the configuration, give it a number up front
  -    for ($idx = 0; $idx <= $#$columns; $idx++) {
  -        $column = $columns->[$idx];
  -        $table_def->{column}{$column}{idx} = $idx;
  -    }
  -
  -    # load up all additional information from the native metadata
  -    $self->load_table_metadata_auto($table);
  -
  -    # for each column in the hash (random order), add them to the end
  -    foreach $column (keys %{$table_def->{column}}) {
  -        $column_def = $table_def->{column}{$column};
  -        $column_def->{name} = $column;
  -        $column_def->{label} = $column if (! $column_def->{label});
  - 
  -        # column has not been added to the list and it's not explicitly "hidden", 
so add it
  -        if (!defined $column_def->{idx} && ! $column_def->{hide}) {
  -            push(@$columns, $column);
  -            $idx = $#$columns;
  -            $column_def->{idx} = $idx;
  -            $column_def->{alias}  = "c$idx" if (!defined $column_def->{alias});
  -
  -            # we're not hiding physical columns and a native table was defined, so 
make an entry
  -            if (! $self->{hide_physical}) {
  -                $native_column = $column_def->{native_column};
  -                if (defined $native_column &&
  -                    $native_column ne $column &&
  -                    !defined $table_def->{column}{$native_column}) {
  -                    $table_def->{column}{$native_column} = 
$table_def->{column}{$column};
  -                }
  -            }
  -        }
  -
  -        $table_def->{column_labels}{$column} = $column_def->{label};
  -    }
  -
  -    # if a primary key is not defined, assume it is the first column
  -    #if (!defined $table_def->{prikey}) {
  -    #    $table_def->{prikey} = [ $table_def->{columns}[0] ];
  -    #}
  -
  -    # predefine that certain required columns will be in the result set
  -    $self->set_required_columns_fetched($table);
  -    $self->clear_cache();
  -}
  -
  -#############################################################################
  -# load_table_metadata_auto()
  -#############################################################################
  -
  -=head2 load_table_metadata_auto()
  -
  -    * Signature: $repository->load_table_metadata_auto();
  -    * Param:     void
  -    * Return:    void
  -    * Throws:    P5EEx::Blue::Exception::Repository
  -    * Since:     0.01
  -
  -    Sample Usage: 
  -
  -    $self->load_table_metadata_auto();
  -
  -Loads metadata for an individual table from the repository itself
  -(to complement metadata in the configuration and perhaps
  -override it).
  -
  -The default implementation does nothing.
  -It is intended to be overridden in the subclass
  -(if the repository has any sort of metadata).
  -
  -=cut
  -
  -sub load_table_metadata_auto {   # OVERRIDE IN SUBCLASS (IF DESIRED)
  -    my ($self, $table) = @_;
  -}
  -
  -#############################################################################
  -# get_type_names()
  -#############################################################################
  -
  -=head2 get_type_names()
  -
  -    * Signature: $typenames = $repository->get_type_names();
  -    * Param:     void
  -    * Return:    $typenames         []
  -    * Throws:    P5EEx::Blue::Exception::Repository
  -    * Since:     0.01
  -
  -    Sample Usage: 
  -
  -    $typenames = $rep->get_type_names();
  -    print join(",", @$typenames), "\n";
  -
  -Returns the standard set of type names for columns in a repository.
  -These are perl-friendly type names which are useful to do data validation.
  -
  -    * string
  -    * text
  -    * integer
  -    * float
  -    * date
  -    * time
  -    * datetime
  -    * binary
  -
  -=cut
  -
  -sub get_type_names {
  -    my ($self) = @_;
  -    $self->{types};
  -}
  -
  -#############################################################################
  -# get_type_labels()
  -#############################################################################
  -
  -=head2 get_type_labels()
  -
  -    * Signature: $typelabels = $repository->get_type_labels();
  -    * Param:     void
  -    * Return:    $typelabels        {}
  -    * Throws:    P5EEx::Blue::Exception::Repository
  -    * Since:     0.01
  -
  -    Sample Usage: 
  -
  -    $typelabels = $rep->get_type_labels();
  -    foreach (sort keys %$typelabels) {
  -        print "$_ => $typelabels->{$_}\n";
  -    }
  -
  -Returns a hash of all of the repository types and the labels
  -which should be used when displaying them to the user through
  -the user interface.
  -
  -    * string   => "Characters"
  -    * text     => "Paragraph"
  -    * integer  => "Integer"
  -    * float    => "Number"
  -    * date     => "Date"
  -    * time     => "Time"
  -    * datetime => "Date and Time"
  -    * binary   => "Binary Data"
  -
  -=cut
  -
  -sub get_type_labels {
  -    my ($self) = @_;
  -    $self->{type_labels};
  -}
  -
  -#############################################################################
  -# get_type_def()
  -#############################################################################
  -
  -=head2 get_type_def()
  -
  -    * Signature: $typedef = $rep->get_type_def($typename);
  -    * Param:     $typename          string
  -    * Return:    $typedef           {}
  -    * Throws:    P5EEx::Blue::Exception::Repository
  -    * Since:     0.01
  -
  -    Sample Usage: 
  -
  -    $typedef = $rep->get_type_def("string");
  -    print "$typedef->{name} $typedef->{label}\n";
  -
  -Gets a reference to a "type definition", which allows you to access all
  -of the attributes of the requested type
  -(currently only "name" and "label").
  -
  -=cut
  -
  -sub get_type_def {
  -    my ($self, $type) = @_;
  -    $self->{type}{$type};
  -}
  -
  -#############################################################################
  -# get_table_names()
  -#############################################################################
  -
  -=head2 get_table_names()
  -
  -    * Signature: $tablenames = $rep->get_table_names();
  -    * Param:     void
  -    * Return:    $tablenames        []
  -    * Throws:    P5EEx::Blue::Exception::Repository
  -    * Since:     0.01
  -
  -    Sample Usage: 
  -
  -    $tablenames = $rep->get_table_names();
  -    print join(",", @$tablenames), "\n";
  -
  -Returns the set of table names in the repository.
  -
  -=cut
  -
  -sub get_table_names {
  -    my ($self) = @_;
  -    $self->{tables};
  -}
  -
  -#############################################################################
  -# get_table_labels()
  -#############################################################################
  -
  -=head2 get_table_labels()
  -
  -    * Signature: $tablelabels = $rep->get_table_labels();
  -    * Param:     void
  -    * Return:    $tablelabels       {}
  -    * Throws:    P5EEx::Blue::Exception::Repository
  -    * Since:     0.01
  -
  -    Sample Usage: 
  -
  -    $tablelabels = $rep->get_table_labels();
  -    foreach (sort keys %$tablelabels) {
  -        print "$_ => $tablelabels->{$_}\n";
  -    }
  -
  -Returns a hash of all of the tables and the labels
  -which should be used when displaying them to the user through
  -the user interface.
  +Returns a hash of all of the tables and the labels
  +which should be used when displaying them to the user through
  +the user interface.
   
   =cut
   
  @@ -1952,12 +1650,254 @@
   }
   
   #############################################################################
  -# get_related_keys()
  +# get_related_keys()
  +#############################################################################
  +
  +=head2 get_related_keys()
  +
  +    * Signature: $tbd_return = $repository->get_related_keys($tbd_param);
  +    * Param:     $tbd_param         integer
  +    * Return:    $tbd_return        integer
  +    * Throws:    P5EEx::Blue::Exception::Repository
  +    * Since:     0.01
  +
  +    Sample Usage: 
  +
  +    $tbd_return = $repository->get_related_keys($tbd_param);
  +
  +=cut
  +
  +# @keys = $rep->get_related_keys($table, $key, $related_table, $relation);
  +# TODO:
  +sub get_related_keys {
  +    my ($self, $table, $key, $related_table, $relation) = @_;
  +    my (@keys);
  +}
  +
  +#############################################################################
  +# PUBLIC METHODS
  +#############################################################################
  +
  +=head1 Public Methods: Cache control
  +
  +=cut
  +
  +#############################################################################
  +# load_cache()
  +#############################################################################
  +
  +=head2 load_cache()
  +
  +    * Signature: $tbd_return = $repository->load_cache($tbd_param);
  +    * Param:     $tbd_param         integer
  +    * Return:    $tbd_return        integer
  +    * Throws:    P5EEx::Blue::Exception::Repository
  +    * Since:     0.01
  +
  +    Sample Usage: 
  +
  +    $tbd_return = $repository->load_cache($tbd_param);
  +
  +=cut
  +
  +# $rep->load_cache();
  +sub load_cache {
  +    my $self = shift;
  +}
  +
  +#############################################################################
  +# clear_cache()
  +#############################################################################
  +
  +=head2 clear_cache()
  +
  +    * Signature: $tbd_return = $repository->clear_cache($tbd_param);
  +    * Param:     $tbd_param         integer
  +    * Return:    $tbd_return        integer
  +    * Throws:    P5EEx::Blue::Exception::Repository
  +    * Since:     0.01
  +
  +    Sample Usage: 
  +
  +    $tbd_return = $repository->clear_cache($tbd_param);
  +
  +=cut
  +
  +# $rep->clear_cache();
  +sub clear_cache {
  +    my ($self, $table) = @_;
  +    my (@tables, $rows);
  +    @tables = (defined $table) ? ($table) : @{$self->{tables}};
  +    
  +    foreach $table (@tables) {
  +        $rows = $self->{table}{$table}{cache}{rows};
  +        if (!defined $rows || ref($rows) ne "ARRAY" || $#$rows > -1) {
  +            $self->{table}{$table}{cache}{rows}   = [];
  +            $self->{table}{$table}{cache}{rowidx} = {};
  +        }
  +    }
  +}
  +
  +#############################################################################
  +# add_columns_fetched()
  +#############################################################################
  +
  +=head2 add_columns_fetched()
  +
  +    * Signature: $tbd_return = $repository->add_columns_fetched($tbd_param);
  +    * Param:     $tbd_param         integer
  +    * Return:    $tbd_return        integer
  +    * Throws:    P5EEx::Blue::Exception::Repository
  +    * Since:     0.01
  +
  +    Sample Usage: 
  +
  +    $tbd_return = $repository->add_columns_fetched($tbd_param);
  +
  +=cut
  +
  +# $rep->add_columns_fetched   ($table, \@cols);
  +# $rep->add_columns_fetched   ($table, \@cols, \@colidx);
  +sub add_columns_fetched {
  +    my ($self, $table, $colsref, $colidxref) = @_;
  +    my ($colidx, $column, $colnum, $columns_added, $cachecolumns);
  +
  +    $colidx = $self->{table}{$table}{cache}{columnidx};
  +    if (!defined $colidx) {
  +        $colidx = {};
  +        $self->{table}{$table}{cache}{columnidx} = $colidx;
  +    }
  +
  +    $cachecolumns = $self->{table}{$table}{cache}{columns};
  +    if (!defined $cachecolumns) {
  +        $cachecolumns = [];
  +        $self->{table}{$table}{cache}{columns} = $cachecolumns;
  +    }
  +
  +    $columns_added = 0;
  +    for ($colnum = 0; $colnum <= $#$colsref; $colnum++) {
  +        $column = $colsref->[$colnum];
  +        if (!defined $colidx->{$column}) {
  +            push(@$cachecolumns, $column);
  +            $colidx->{$column} = $#$cachecolumns;
  +            $columns_added = 1;
  +        }
  +        $colidxref->[$colnum] = $colidx->{$column} if (ref($colidxref) eq "ARRAY");
  +    }
  +
  +    if ($columns_added) {  # clear the cache
  +        $self->clear_cache($table);
  +    }
  +}
  +
  +#############################################################################
  +# set_required_columns_fetched()
  +#############################################################################
  +
  +=head2 set_required_columns_fetched()
  +
  +    * Signature: $tbd_return = 
$repository->set_required_columns_fetched($tbd_param);
  +    * Param:     $tbd_param         integer
  +    * Return:    $tbd_return        integer
  +    * Throws:    P5EEx::Blue::Exception::Repository
  +    * Since:     0.01
  +
  +    Sample Usage: 
  +
  +    $tbd_return = $repository->set_required_columns_fetched($tbd_param);
  +
  +=cut
  +
  +# $rep->set_required_columns_fetched($table);
  +sub set_required_columns_fetched {
  +    my ($self, $table) = @_;
  +    my ($prikeycolumns, @prikeyidx);
  +    $prikeycolumns = $self->{table}{$table}{prikey};
  +    $self->add_columns_fetched($table, $prikeycolumns, \@prikeyidx);
  +    $self->{table}{$table}{prikeyidx} = \@prikeyidx;
  +}
  +
  +#############################################################################
  +# clear_columns_fetched()
  +#############################################################################
  +
  +=head2 clear_columns_fetched()
  +
  +    * Signature: $tbd_return = $repository->clear_columns_fetched($tbd_param);
  +    * Param:     $tbd_param         integer
  +    * Return:    $tbd_return        integer
  +    * Throws:    P5EEx::Blue::Exception::Repository
  +    * Since:     0.01
  +
  +    Sample Usage: 
  +
  +    $tbd_return = $repository->clear_columns_fetched($tbd_param);
  +
  +=cut
  +
  +# $rep->clear_columns_fetched ($table);
  +sub clear_columns_fetched {
  +    my ($self, $table) = @_;
  +    $self->{table}{$table}{cache}{columnidx} = {};
  +    $self->{table}{$table}{cache}{columns} = [];
  +    $self->set_required_columns_fetched($table);
  +}
  +
  +#############################################################################
  +# set_row_hint()
  +#############################################################################
  +
  +=head2 set_row_hint()
  +
  +    * Signature: $tbd_return = $repository->set_row_hint($tbd_param);
  +    * Param:     $tbd_param         integer
  +    * Return:    $tbd_return        integer
  +    * Throws:    P5EEx::Blue::Exception::Repository
  +    * Since:     0.01
  +
  +    Sample Usage: 
  +
  +    $tbd_return = $repository->set_row_hint($tbd_param);
  +
  +=cut
  +
  +# $rep->set_row_hint ($table, \%paramvalues);
  +sub set_row_hint {
  +    my ($self, $table, $paramvalueshashref) = @_;
  +    $self->{table}{$table}{cache}{paramvalues} = { %$paramvalueshashref };
  +}
  +
  +#############################################################################
  +# clear_row_hint()
  +#############################################################################
  +
  +=head2 clear_row_hint()
  +
  +    * Signature: $tbd_return = $repository->clear_row_hint($tbd_param);
  +    * Param:     $tbd_param         integer
  +    * Return:    $tbd_return        integer
  +    * Throws:    P5EEx::Blue::Exception::Repository
  +    * Since:     0.01
  +
  +    Sample Usage: 
  +
  +    $tbd_return = $repository->clear_row_hint($tbd_param);
  +
  +=cut
  +
  +# $rep->clear_row_hint    ($table);
  +sub clear_row_hint {
  +    my ($self, $table) = @_;
  +    $self->{table}{$table}{cache}{paramvalues} = {};
  +}
  +
  +#############################################################################
  +# get_required_columns()
   #############################################################################
   
  -=head2 get_related_keys()
  +=head2 get_required_columns()
   
  -    * Signature: $tbd_return = $repository->get_related_keys($tbd_param);
  +    * Signature: $tbd_return = $repository->get_required_columns($tbd_param);
       * Param:     $tbd_param         integer
       * Return:    $tbd_return        integer
       * Throws:    P5EEx::Blue::Exception::Repository
  @@ -1965,32 +1905,31 @@
   
       Sample Usage: 
   
  -    $tbd_return = $repository->get_related_keys($tbd_param);
  +    $tbd_return = $repository->get_required_columns($tbd_param);
   
   =cut
   
  -# @keys = $rep->get_related_keys($table, $key, $related_table, $relation);
  -# TODO:
  -sub get_related_keys {
  -    my ($self, $table, $key, $related_table, $relation) = @_;
  -    my (@keys);
  +# @columns = $rep->get_required_columns($table);
  +sub get_required_columns {
  +    my ($self, $table) = @_;
  +    my (@columns);
   }
   
   #############################################################################
   # PUBLIC METHODS
   #############################################################################
   
  -=head1 Public Methods: Cache control
  +=head1 Public Methods: Transaction Control
   
   =cut
   
   #############################################################################
  -# load_cache()
  +# commit()
   #############################################################################
   
  -=head2 load_cache()
  +=head2 commit()
   
  -    * Signature: $tbd_return = $repository->load_cache($tbd_param);
  +    * Signature: $tbd_return = $repository->commit($tbd_param);
       * Param:     $tbd_param         integer
       * Return:    $tbd_return        integer
       * Throws:    P5EEx::Blue::Exception::Repository
  @@ -1998,22 +1937,43 @@
   
       Sample Usage: 
   
  -    $tbd_return = $repository->load_cache($tbd_param);
  +    $tbd_return = $repository->commit($tbd_param);
   
   =cut
   
  -# $rep->load_cache();
  -sub load_cache {
  +# $rep->commit();
  +sub commit {
       my $self = shift;
  +    my ($table, $rows, $rowidx, $rowchange, $change, $colref, $prikeyidx);
  +    foreach $table (@{$self->{tables}}) {
  +        $prikeyidx = $self->{table}{$table}{prikeyidx};
  +        $rows      = $self->{table}{$table}{cache}{rows};
  +        $rowchange = $self->{table}{$table}{cache}{rowchange};
  +        $colref    = $self->{table}{$table}{cache}{columns};
  +        if ($#$rowchange > -1) {
  +            for ($rowidx = 0; $rowidx <= $#$rows; $rowidx++) {
  +                $change = $rowchange->[$rowidx];
  +                next if (!defined $change);
  +                if ($change eq "U") {
  +                    $self->update_row($table, $colref, $rows->[$rowidx], 
$prikeyidx);
  +                    $rowchange->[$rowidx] = "";
  +                }
  +                elsif ($change eq "I") {
  +                    $self->insert_row($table, $colref, $rows->[$rowidx]);
  +                    $rowchange->[$rowidx] = "";
  +                }
  +            }
  +        }
  +    }
   }
   
   #############################################################################
  -# clear_cache()
  +# rollback()
   #############################################################################
   
  -=head2 clear_cache()
  +=head2 rollback()
   
  -    * Signature: $tbd_return = $repository->clear_cache($tbd_param);
  +    * Signature: $tbd_return = $repository->rollback($tbd_param);
       * Param:     $tbd_param         integer
       * Return:    $tbd_return        integer
       * Throws:    P5EEx::Blue::Exception::Repository
  @@ -2021,325 +1981,417 @@
   
       Sample Usage: 
   
  -    $tbd_return = $repository->clear_cache($tbd_param);
  +    $tbd_return = $repository->rollback($tbd_param);
   
   =cut
   
  -# $rep->clear_cache();
  -sub clear_cache {
  -    my ($self, $table) = @_;
  -    my (@tables, $rows);
  -    @tables = (defined $table) ? ($table) : @{$self->{tables}};
  -    
  -    foreach $table (@tables) {
  -        $rows = $self->{table}{$table}{cache}{rows};
  -        if (!defined $rows || ref($rows) ne "ARRAY" || $#$rows > -1) {
  -            $self->{table}{$table}{cache}{rows}   = [];
  -            $self->{table}{$table}{cache}{rowidx} = {};
  -        }
  -    }
  +# $rep->rollback();
  +sub rollback {
  +    my $self = shift;
   }
   
   #############################################################################
  -# add_columns_fetched()
  +# PUBLIC METHODS
   #############################################################################
   
  -=head2 add_columns_fetched()
  +=head1 Public Methods: Miscellaneous
   
  -    * Signature: $tbd_return = $repository->add_columns_fetched($tbd_param);
  -    * Param:     $tbd_param         integer
  -    * Return:    $tbd_return        integer
  +=cut
  +
  +#############################################################################
  +# serial()
  +#############################################################################
  +
  +=head2 serial()
  +
  +    * Signature: $serial_num = $repository->serial($category);
  +    * Param:     $category          string
  +    * Return:    $serial_num        integer
       * Throws:    P5EEx::Blue::Exception::Repository
       * Since:     0.01
   
       Sample Usage: 
   
  -    $tbd_return = $repository->add_columns_fetched($tbd_param);
  +    $serial_num = $repository->serial($category);
   
   =cut
   
  -# $rep->add_columns_fetched   ($table, \@cols);
  -# $rep->add_columns_fetched   ($table, \@cols, \@colidx);
  -sub add_columns_fetched {
  -    my ($self, $table, $colsref, $colidxref) = @_;
  -    my ($colidx, $column, $colnum, $columns_added, $cachecolumns);
  -
  -    $colidx = $self->{table}{$table}{cache}{columnidx};
  -    if (!defined $colidx) {
  -        $colidx = {};
  -        $self->{table}{$table}{cache}{columnidx} = $colidx;
  -    }
  -
  -    $cachecolumns = $self->{table}{$table}{cache}{columns};
  -    if (!defined $cachecolumns) {
  -        $cachecolumns = [];
  -        $self->{table}{$table}{cache}{columns} = $cachecolumns;
  +my %serial_number;
  +sub serial {
  +    my ($self, $category) = @_;
  +    if (!defined $serial_number{$category}) {
  +        $serial_number{$category} = 1;
  +        return 1;
       }
  -
  -    $columns_added = 0;
  -    for ($colnum = 0; $colnum <= $#$colsref; $colnum++) {
  -        $column = $colsref->[$colnum];
  -        if (!defined $colidx->{$column}) {
  -            push(@$cachecolumns, $column);
  -            $colidx->{$column} = $#$cachecolumns;
  -            $columns_added = 1;
  +    else {
  +        return ++$serial_number{$category};
           }
  -        $colidxref->[$colnum] = $colidx->{$column} if (ref($colidxref) eq "ARRAY");
       }
   
  -    if ($columns_added) {  # clear the cache
  -        $self->clear_cache($table);
  -    }
  -}
  +#############################################################################
  +# PROTECTED METHODS
  +#############################################################################
  +
  +=head1 Protected Methods: Metadata
  +
  +=cut
   
   #############################################################################
  -# set_required_columns_fetched()
  +# load_rep_metadata()
   #############################################################################
   
  -=head2 set_required_columns_fetched()
  +=head2 load_rep_metadata()
   
  -    * Signature: $tbd_return = 
$repository->set_required_columns_fetched($tbd_param);
  -    * Param:     $tbd_param         integer
  -    * Return:    $tbd_return        integer
  +    * Signature: $repository->load_rep_metadata();
  +    * Param:     void
  +    * Return:    void
       * Throws:    P5EEx::Blue::Exception::Repository
       * Since:     0.01
   
       Sample Usage: 
   
  -    $tbd_return = $repository->set_required_columns_fetched($tbd_param);
  +    $self->load_rep_metadata();
  +
  +Initializes the repository metadata information from the config.
  +
  +    * List of tables (+ displayable labels)
  +    * List of column types (+ displayable labels)
  +
  +Then it calls load_rep_metadata_auto() in order for the repository
  +itself to be consulted for its metadata information.
   
   =cut
   
  -# $rep->set_required_columns_fetched($table);
  -sub set_required_columns_fetched {
  -    my ($self, $table) = @_;
  -    my ($prikeycolumns, @prikeyidx);
  -    $prikeycolumns = $self->{table}{$table}{prikey};
  -    $self->add_columns_fetched($table, $prikeycolumns, \@prikeyidx);
  -    $self->{table}{$table}{prikeyidx} = \@prikeyidx;
  +# load metadata about TYPES supported by the repository
  +# and the list of TABLES in it.
  +sub load_rep_metadata {
  +    my ($self) = @_;
  +
  +    my ($table, $tables, $table_defs, $table_def, $native_table, $idx);
  +
  +    # start with the list of tables that was configured (or the empty list)
  +    $tables = $self->{tables};
  +    if (!defined $tables) {
  +        $tables = [];
  +        $self->{tables} = $tables;
   }
   
  -#############################################################################
  -# clear_columns_fetched()
  -#############################################################################
  +    # start with the hash of tables defined (or the empty hash)
  +    $table_defs = $self->{table};
  +    if (!defined $table_defs) {
  +        $table_defs = {};
  +        $self->{table} = $table_defs;
  +    }
   
  -=head2 clear_columns_fetched()
  +    # for each table named in the configuration, give it a number up front
  +    for ($idx = 0; $idx <= $#$tables; $idx++) {
  +        $table = $tables->[$idx];
  +        $table_defs->{$table}{idx} = $idx;
  +    }
   
  -    * Signature: $tbd_return = $repository->clear_columns_fetched($tbd_param);
  -    * Param:     $tbd_param         integer
  -    * Return:    $tbd_return        integer
  -    * Throws:    P5EEx::Blue::Exception::Repository
  -    * Since:     0.01
  +    # for each table in the hash (random order), add them to the end
  +    foreach $table (keys %$table_defs) {
  +        $table_def = $table_defs->{$table};
  +        $table_def->{name} = $table;
  +        $table_def->{label} = $table if (! $table_def->{label});
   
  -    Sample Usage: 
  +        # table has not been added to the list and it's not explicitly "hidden", so 
add it
  +        if (!defined $table_def->{idx} && ! $table_def->{hide}) {
  +            push(@$tables, $table);
  +            $table_def->{idx} = $#$tables;
   
  -    $tbd_return = $repository->clear_columns_fetched($tbd_param);
  +            # we're not hiding physical tables and a native table was defined, so 
make an entry
  +            if (! $self->{hide_physical}) {
  +                $native_table = $table_def->{native_table};
  +                if (defined $native_table) {
  +                    $table_defs->{$native_table} = $table_defs->{$table};
  +                }
  +            }
  +        }
   
  -=cut
  +        $self->{table_labels}{$table} = $table_def->{label};
  +    }
   
  -# $rep->clear_columns_fetched ($table);
  -sub clear_columns_fetched {
  -    my ($self, $table) = @_;
  -    $self->{table}{$table}{cache}{columnidx} = {};
  -    $self->{table}{$table}{cache}{columns} = [];
  -    $self->set_required_columns_fetched($table);
  +    my ($type, $types, $type_defs);
  +
  +    # start with the hash of types defined (or the empty hash)
  +    $type_defs = $self->{type};
  +    if (!defined $type_defs) {
  +        $type_defs = {};
  +        $self->{type} = $type_defs;
  +    }
  +
  +    # define the standard list of Repository types
  +    $types = [ "string", "text", "integer", "float", "date", "time", "datetime", 
"binary" ];
  +    $self->{types} = $types;
  +
  +    # define the standard list of Repository labels
  +    $self->{type_labels} = {
  +        "string"   => "Characters",
  +        "text"     => "Paragraph",
  +        "integer"  => "Integer",
  +        "float"    => "Number",
  +        "date"     => "Date",
  +        "time"     => "Time",
  +        "datetime" => "Date and Time",
  +        "binary"   => "Binary Data",
  +    };
  +
  +    # figure the index in the array of each type
  +    for ($idx = 0; $idx <= $#$types; $idx++) {
  +        $type = $types->[$idx];
  +        $self->{type}{$type}{idx} = $idx;
  +    }
  +
  +    # load up all additional information from the native metadata
  +    $self->load_rep_metadata_auto();
   }
   
   #############################################################################
  -# set_row_hint()
  +# load_rep_metadata_auto()
   #############################################################################
   
  -=head2 set_row_hint()
  +=head2 load_rep_metadata_auto()
   
  -    * Signature: $tbd_return = $repository->set_row_hint($tbd_param);
  -    * Param:     $tbd_param         integer
  -    * Return:    $tbd_return        integer
  +    * Signature: $repository->load_rep_metadata_auto();
  +    * Param:     void
  +    * Return:    void
       * Throws:    P5EEx::Blue::Exception::Repository
       * Since:     0.01
   
       Sample Usage: 
   
  -    $tbd_return = $repository->set_row_hint($tbd_param);
  +    $repository->load_rep_metadata_auto();
  +
  +Loads repository metadata from the repository itself
  +(to complement metadata in the configuration and perhaps
  +override it).
  +
  +The default implementation does nothing.
  +It is intended to be overridden in the subclass
  +(if the repository has any sort of metadata).
   
   =cut
   
  -# $rep->set_row_hint ($table, \%paramvalues);
  -sub set_row_hint {
  -    my ($self, $table, $paramvalueshashref) = @_;
  -    $self->{table}{$table}{cache}{paramvalues} = { %$paramvalueshashref };
  +sub load_rep_metadata_auto {     # OVERRIDE IN SUBCLASS (IF DESIRED)
  +    my ($self) = @_;
   }
   
   #############################################################################
  -# clear_row_hint()
  +# load_table_metadata()
   #############################################################################
   
  -=head2 clear_row_hint()
  +=head2 load_table_metadata()
   
  -    * Signature: $tbd_return = $repository->clear_row_hint($tbd_param);
  -    * Param:     $tbd_param         integer
  -    * Return:    $tbd_return        integer
  +    * Signature: $self->load_table_metadata();
  +    * Param:     void
  +    * Return:    void
       * Throws:    P5EEx::Blue::Exception::Repository
       * Since:     0.01
   
       Sample Usage: 
   
  -    $tbd_return = $repository->clear_row_hint($tbd_param);
  -
  -=cut
  -
  -# $rep->clear_row_hint    ($table);
  -sub clear_row_hint {
  -    my ($self, $table) = @_;
  -    $self->{table}{$table}{cache}{paramvalues} = {};
  -}
  -
  -#############################################################################
  -# get_required_columns()
  -#############################################################################
  +    $self->load_table_metadata();
   
  -=head2 get_required_columns()
  +First it calls load_table_metadata_auto() in order for the repository
  +itself to be consulted for any metadata information for the about the
  +table.
   
  -    * Signature: $tbd_return = $repository->get_required_columns($tbd_param);
  -    * Param:     $tbd_param         integer
  -    * Return:    $tbd_return        integer
  -    * Throws:    P5EEx::Blue::Exception::Repository
  -    * Since:     0.01
  +Then it initializes
  +the repository metadata information for that table from the config
  +information.
   
  -    Sample Usage: 
  +    * List of columns (+ displayable labels, types)
  +    * List of column types (+ displayable labels)
   
  -    $tbd_return = $repository->get_required_columns($tbd_param);
  +Then it determines the set of required columns whenever selecting
  +data from the table and clears the cache of selected rows
  +for the table.
   
   =cut
   
  -# @columns = $rep->get_required_columns($table);
  -sub get_required_columns {
  +# load detailed metadata about a particular table, including
  +# the details about each column
  +sub load_table_metadata {
       my ($self, $table) = @_;
  -    my (@columns);
  -}
  -
  -#############################################################################
  -# PUBLIC METHODS
  -#############################################################################
   
  -=head1 Public Methods: Transaction Control
  +    # if it's already been loaded, don't do it again
  +    return if (defined $self->{table}{$table}{loaded});
  +    $self->{table}{$table}{loaded} = 1;   # mark it as having been loaded
   
  -=cut
  +    my ($table_def, $columns, $column, $column_def, $idx, $native_column);
   
  -#############################################################################
  -# commit()
  -#############################################################################
  +    $table_def = $self->{table}{$table};
  +    return if (!defined $table_def);
   
  -=head2 commit()
  +    $columns = $table_def->{columns};
  +    if (! defined $columns) {
  +        $columns = [];
  +        $table_def->{columns} = $columns;
  +    }
   
  -    * Signature: $tbd_return = $repository->commit($tbd_param);
  -    * Param:     $tbd_param         integer
  -    * Return:    $tbd_return        integer
  -    * Throws:    P5EEx::Blue::Exception::Repository
  -    * Since:     0.01
  +    # for each column named in the configuration, give it a number up front
  +    for ($idx = 0; $idx <= $#$columns; $idx++) {
  +        $column = $columns->[$idx];
  +        $table_def->{column}{$column}{idx} = $idx;
  +    }
   
  -    Sample Usage: 
  +    # load up all additional information from the native metadata
  +    $self->load_table_metadata_auto($table);
   
  -    $tbd_return = $repository->commit($tbd_param);
  +    # for each column in the hash (random order), add them to the end
  +    foreach $column (keys %{$table_def->{column}}) {
  +        $column_def = $table_def->{column}{$column};
  +        $column_def->{name} = $column;
  +        $column_def->{label} = $column if (! $column_def->{label});
   
  -=cut
  +        # column has not been added to the list and it's not explicitly "hidden", 
so add it
  +        if (!defined $column_def->{idx} && ! $column_def->{hide}) {
  +            push(@$columns, $column);
  +            $idx = $#$columns;
  +            $column_def->{idx} = $idx;
  +            $column_def->{alias}  = "c$idx" if (!defined $column_def->{alias});
   
  -# $rep->commit();
  -sub commit {
  -    my $self = shift;
  -    my ($table, $rows, $rowidx, $rowchange, $change, $colref, $prikeyidx);
  -    foreach $table (@{$self->{tables}}) {
  -        $prikeyidx = $self->{table}{$table}{prikeyidx};
  -        $rows      = $self->{table}{$table}{cache}{rows};
  -        $rowchange = $self->{table}{$table}{cache}{rowchange};
  -        $colref    = $self->{table}{$table}{cache}{columns};
  -        if ($#$rowchange > -1) {
  -            for ($rowidx = 0; $rowidx <= $#$rows; $rowidx++) {
  -                $change = $rowchange->[$rowidx];
  -                next if (!defined $change);
  -                if ($change eq "U") {
  -                    $self->update_row($table, $colref, $rows->[$rowidx], 
$prikeyidx);
  -                    $rowchange->[$rowidx] = "";
  -                }
  -                elsif ($change eq "I") {
  -                    $self->insert_row($table, $colref, $rows->[$rowidx]);
  -                    $rowchange->[$rowidx] = "";
  +            # we're not hiding physical columns and a native table was defined, so 
make an entry
  +            if (! $self->{hide_physical}) {
  +                $native_column = $column_def->{native_column};
  +                if (defined $native_column &&
  +                    $native_column ne $column &&
  +                    !defined $table_def->{column}{$native_column}) {
  +                    $table_def->{column}{$native_column} = 
$table_def->{column}{$column};
                   }
               }
           }
  +
  +        $table_def->{column_labels}{$column} = $column_def->{label};
       }
  +
  +    # if a primary key is not defined, assume it is the first column
  +    #if (!defined $table_def->{prikey}) {
  +    #    $table_def->{prikey} = [ $table_def->{columns}[0] ];
  +    #}
  +
  +    # predefine that certain required columns will be in the result set
  +    $self->set_required_columns_fetched($table);
  +    $self->clear_cache();
   }
   
   #############################################################################
  -# rollback()
  +# load_table_metadata_auto()
   #############################################################################
   
  -=head2 rollback()
  +=head2 load_table_metadata_auto()
   
  -    * Signature: $tbd_return = $repository->rollback($tbd_param);
  -    * Param:     $tbd_param         integer
  -    * Return:    $tbd_return        integer
  +    * Signature: $repository->load_table_metadata_auto();
  +    * Param:     void
  +    * Return:    void
       * Throws:    P5EEx::Blue::Exception::Repository
       * Since:     0.01
   
       Sample Usage: 
   
  -    $tbd_return = $repository->rollback($tbd_param);
  +    $self->load_table_metadata_auto();
  +
  +Loads metadata for an individual table from the repository itself
  +(to complement metadata in the configuration and perhaps
  +override it).
  +
  +The default implementation does nothing.
  +It is intended to be overridden in the subclass
  +(if the repository has any sort of metadata).
   
   =cut
   
  -# $rep->rollback();
  -sub rollback {
  -    my $self = shift;
  +sub load_table_metadata_auto {   # OVERRIDE IN SUBCLASS (IF DESIRED)
  +    my ($self, $table) = @_;
   }
   
   #############################################################################
  -# PUBLIC METHODS
  +# PROTECTED METHODS
   #############################################################################
   
  -=head1 Public Methods: Miscellaneous
  +=head1 Protected Methods: Miscellaneous
   
   =cut
   
  -#############################################################################
  -# serial()
  -#############################################################################
  +#####################################################################
  +# init()
  +#####################################################################
   
  -=head2 serial()
  +=head2 init()
   
  -    * Signature: $serial_num = $repository->serial($category);
  -    * Param:     $category          string
  -    * Return:    $serial_num        integer
  +    * Signature: $repository->init();
  +    * Signature: $repository->init($named);
  +    * Param:     deferConnection     integer
  +    * Return:    void
       * Throws:    P5EEx::Blue::Exception::Repository
       * Since:     0.01
   
       Sample Usage: 
   
  -    $serial_num = $repository->serial($category);
  +    $self->init();
  +
  +Every Service constructor (Repository is derived from Service) will
  +invoke the init() method near the end of object construction.
  +
  +The standard behavior for repositories (implemented here) in init() is
  +to initialize the "numrows" and "error" attributes,
  +call init2(), connect to the repository,
  +and load the repository metadata.
   
   =cut
   
  -my %serial_number;
  -sub serial {
  -    my ($self, $category) = @_;
  -    if (!defined $serial_number{$category}) {
  -        $serial_number{$category} = 1;
  -        return 1;
  +sub init {
  +    my ($self, $args) = @_;
  +    my ($dbidriver, $dbname, $dbuser, $dbpass, $dbioptions, $dbschema);
  +    my ($name);
  +
  +    $self->{numrows} = 0;
  +    $self->{error}   = "";
  +
  +    $self->init2($args);
  +
  +    if (!$self->{deferConnection} && !$self->connect()) {
  +        print STDERR "Error on connect():";
  +        foreach (keys %$self) {
  +            print STDERR " $_=[", $self->{$_}, "]";
       }
  -    else {
  -        return ++$serial_number{$category};
  +        print STDERR "\n";
  +        return(undef);
       }
  +
  +    $self->load_rep_metadata();
   }
   
   #############################################################################
  -# PROTECTED METHODS
  +# init2()
   #############################################################################
   
  -=head1 Protected Methods:
  +=head2 init2()
  +
  +    * Signature: $repository->init2();
  +    * Signature: $repository->init2($named);
  +    * Param:     deferConnection    integer
  +    * Return:    void
  +    * Throws:    P5EEx::Blue::Exception::Repository
  +    * Since:     0.01
  +
  +    Sample Usage: 
  +
  +    $self->init2();
  +
  +The default behavior of init2() does nothing
  +and is intended to be overridden (if necessary) in the subclass which
  +implements the details of access to the physical data store.
   
   =cut
   
  +sub init2 {    # OVERRIDE IN SUBCLASS TO GET NON-DEFAULT CAPABILITIES
  +    my $self = shift;
  +}
  +
   #############################################################################
  -# Method: service_type()
  +# service_type()
   #############################################################################
   
   =head2 service_type()
  
  
  


Reply via email to