CGI-Application-Framework

 view release on metacpan or  search on metacpan

lib/CGI/Application/Framework.pm  view on Meta::CPAN

applications.

If you want to have a different database connection for different
applications you have a couple of strategies available to you.

=head3 Database Config - Per Project

After setting up your database in the previous section, your site-wide
framework.conf file should contain a section like the following:

    <db_example>
        dsn           = DBI:mysql:database=example
        username      = rdice
        password      = seekrit
    </db_example>

The C<example> in the section name C<db_example> means that this section
applies only to the Example project.

To add a database connection for another project, e.g. named C<Finance>, add
another section:

    <db_finance>
        dsn           = DBI:Pg:dbname=finance
        username      = rdice
        password      = sooper-seekrit
    </db_finance>

(Note that the names of these database sections is somewhat
conventional; you can override these names in your application's
database modules.)

Since these are project-specific configurations, you are quite free to
put them in their respective project framework.conf files.  That is, you
can put the <db_example> section in:

    projects/Example/framework.conf

And you can put the <db_finance> section in:

    projects/Finance/framework.conf

Or you can keep them both in the site-wide file:

    projects/framework.conf

It's up to you how you choose to organize your configuration.

=head3 Database Config - Per Application

If you have two applications in the same project that each need a
different database handle, then you can do this in one of two ways.
The first option is to move the database configuration into the
application-specific framework.conf:

    projects/Finance/receivable/framework.conf

    <db_finance>
        dsn           = DBI:Pg:dbname=receivables
        username      = abbot
        password      = guessme
    </db_finance>

    projects/Finance/payable/framework.conf

    <db_finance>
        dsn           = DBI:mysql:database=payables
        username      = costello
        password      = letmein
    </db_finance>

The other option is to use the URL matching and Application matching
features of the underlying C<Config::Context> system.  For instance:

    projects/framework.conf

    <LocationMatch receiveables>
        <db_finance>
            dsn           = DBI:Pg:dbname=receivables
            username      = abbot
            password      = guessme
        </db_finance>
    </LocationMatch>

    <LocationMatch payables>
        <db_finance>
            dsn           = DBI:mysql:database=payables
            username      = costello
            password      = letmein
        </db_finance>
    </LocationMatch>

For more information on the <LocationMatch> directive and other run-time
configuration matching features, see the documentation for
CGI::Application::Plugin::Config::Context:

    http://search.cpan.org/dist/CGI-Application-Plugin-Config-Context/lib/CGI/Application/Plugin/Config/Context.pm

=head3 Database Config - Per Site

If you want to have multiple Apache virtual hosts running the same
C<CGI::Application::Framework> applications, then you can use the site
matching features of the configuration system:

    projects/framework.conf

    <Site CREDIT>
        <db_finance>
            dsn           = DBI:Pg:dbname=receivables
            username      = abbot
            password      = guessme
        </db_finance>
    </Site>

    <Site DEBIT>
        <db_finance>
            dsn           = DBI:mysql:database=payables
            username      = costello
            password      = letmein
        </db_finance>
    </Site>

To make this work, you will have to set an environment variable in the
C<< <Virtualhost> >> section in your Apache C<httpd.conf>

    <VirtualHost *>
        ServerName www.wepayu.com
        SetEnv SITE_NAME DEBIT
        # .... other per-host configuration goes here
    </VirtualHost>

    <VirtualHost *>
        ServerName www.youpayus.com
        SetEnv SITE_NAME CREDIT
        # .... other per-host configuration goes here
    </VirtualHost>

If you are mixing and matching databases, and you are running under a
persistent environment such as mod_perl, then you must make sure that
all of the schemas of all the databases you are using are identical as
far as C<Class::DBI> is concerned.  In practice that means that the
following items must be the same across databases:

    * table names
    * column names
    * which columns are primary keys

Other database details (such as how columns are indexed) may safely
differ from database to database.


=head1 DATABASE INSTALLATION

If you already have a database set up and you don't need to load the
example data for the Example applications to work, then you can skip
this section.

The Framework and its example programs support many databases.  In
theory, any database that has a C<DBD::*> driver and a C<Class::DBI::*>
subclass module is supported.  This distribution contains explicit
support for C<MySQL>, C<PostgreSQL> and C<SQLite>.  There are instructions for
setting up each of these databases below.

If you like you can use more than one of these databases at the same
time.  See L<"Using multiple database configurations"> below.

=head2 Database Installation - MySQL

This is how to create a MySQL database that works with the Example
applications.

lib/CGI/Application/Framework.pm  view on Meta::CPAN

                # in the subclass that is allowed to know about the
                # specific structure of the login authentication form.
                # -------------------------------------------------------

                my $errs = $self->_relogin_failed_errors
                    (
                     $is_login_authenticated,
                     $user
                     );

                $self->param( _errs => $errs );
                $self->prerun_mode('relogin');

                return;
                # -------------------------------------------------------
            }

        } else {

            $self->log->debug("Looks like we didn't come from 'relogin'");

            if ( $self->_relogin_test() ) {

                # ------------------------------------------------------
                # no problems with time-out check, so continue with
                # web application run...
                # ------------------------------------------------------
                return; # these aren't the droids we're looking for
                # ------------------------------------------------------

            } else {

                # ------------------------------------------------------
                # The session time-out'd, therefore make them cough up a
                # new password, first by redirecting them to a form.
                #
                # Note that the state of the $self-query is saved in
                # the session, so that it may be reconstituted later,
                # for the sake of figuring out where the submit-to
                # run mode was supposed to be, so that form submission
                # data is not lost due to a timeout, etc.
                # ------------------------------------------------------
                my $session_query = '';
                {
                    local $Data::Dumper::Indent = 0;
                    # local $Data::Dumper::Useqq  = 1;  # this creates problems
                    $session_query
                        = Data::Dumper->Dump([$self->query], [ '$query' ]);
                }
                $session_query =~ s/\$query = //;
                $session_query =~ s/;$//;
                $self->session->{_cgi_query} = $session_query;
                $self->prerun_mode('relogin');
                return;
                # ------------------------------------------------------

            } # end of if $self->_relogin_test
        }
    }

    return; # guess that's about it...
}


# ------------------------------------------------------------------
# These methods are new and unique to CGI::Application::Framework
# ------------------------------------------------------------------
sub _make_run_mode_tag {

    my $self   = shift;
    my %params = @_;

    my $whichmode = undef;

    if ( $params{whichmode} eq 'COMEFROM' ) {
        $whichmode = 'come_from_' . $self->mode_param();
    } elsif ( $params{whichmode} eq 'CURRENT' ) {
        $whichmode = 'current_' . $self->mode_param();
    } elsif ( $params{whichmode} eq 'SUBMITTO' ) {
        $whichmode = $self->mode_param();
    } else {
        $self->log_confess("Unsupported run mode [$params{whichmode}] ");
    }

    return
        '<input type=hidden name="'
        . $whichmode
        . '" value="'
        . $self->query->escapeHTML($params{modevalue})
        . '">';
}

sub _param_read_and_set {

    my $self = shift;
    my $param = shift;

    my $value = $self->param($param);
    $self->param($param => ($value || 1));
    return $value;
}

sub _param_read_and_unset {

    my $self = shift;
    my $param = shift;

    my $value = $self->param($param);
    $self->param($param => undef);
    return $value;
}

sub make_self_url {

    my $self = shift;

    # -----------------------------------------------------------------------
    # I had to do all this ugly stuff to create a URL + query string
    # (the latter if necessary) because a simple $self->query->url(-query=>1)
    # was doing weird stuff, like joining key/value pairs with ';' instead
    # of '&', and building the query string out of the full form submission,



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