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 )