[Catalyst] Accessing DB from external model
Darren Duncan
darren at darrenduncan.net
Fri Nov 5 16:50:01 GMT 2010
Mike Raynham wrote:
> Here, the connection information is moved from MyApp::Model::DB to
> MyApp::DB, and then Catalyst::Model::Adaptor is used to glue
> MyApp::Model::DB to MyApp::DB. Is it a good idea? MyApp::Model::DB
> appears to be part of the Catalyst application, so if I want to access
> the database from an external model, it makes sense to me to move the
> connection code outside of the Catalyst application.
What you want to do is turn all the stuff that mediates access to the database
into your own shared library formatted kind of like one you might find as a CPAN
module, say "MyDBLib", and then "use" it in your Catalyst application by way of
Catalyst::Model::Adaptor.
For any configuration details that might vary either per application or per
deployment, make these user-configurable parameters of MyDBLib, with then each
of your applications would supply arguments to it when instantiating a MyDBLib
object; in the Catalyst app's case, said arguments would be in your Catalyst app
config file as is normal for MyApp::Model::DB.
For any configuration details that are unlikely to vary per application or per
deployment, especially if they are details for which your actual code would
vary, then put these directly in your MyDBLib code instead.
Octavian Rasnita wrote:
> The best idea would be to put the connection information in the application's config file like in the example below. (This example uses a Perl data structure, but you can use any configuration type accepted by Config::Any).
>
> 'Model::DB' => {
> schema_class => 'MyApp::Schema',
> connect_info => {
> dsn => 'dbi:Oracle:host=10.10.10.10;port=1521;sid=ora8',
> user => 'user',
> password => "password",
> #name_sep => '.',
> LongReadLen => 100*1024*1024,
> LongTruncOk => 1,
> on_connect_call => 'datetime_setup',
> on_connect_do => [
> "alter session set NLS_COMP='LINGUISTIC'",
> "alter session set NLS_SORT='BINARY_AI'",
> ],
> },
> },
>
> The model will access the connection information directly if it is defined in the config file, and you can use the data from this config file in any other external program.
> You can use the module Config::JFDI for using the Catalyst config file easier.
Now some of this looks wrong to me; a lot of those details should be in your
MyDBLib code instead of the config file. Your config file should instead look
more like this:
'Model::DB' => {
schema_class => 'MyApp::Schema',
connect_info => {
host => '10.10.10.10',
port => 1521,
user => 'user',
password => "password",
},
},
These are more details that a non-programmer user would set.
The other details should all be in your code instead, because users shouldn't
have to know and in particular if they are changed your code could break. In
particular I'm thinking of stuff like "on_connect_call" or the fact you are
using "dbi:Oracle".
Where it can get fuzzier is if your application is cross-DBMS portable, in which
case more info would need to be in the config file, but you'd want to abstract
it somehow, such as users just naming the DBMS and then they are actually
picking from a pre-defined profile which has the code-specific details. But if
the app isn't supposed to be portable, eg if it uses Oracle-specific stuff, then
don't put dbi:Oracle and NLS* and that stuff in your user config file.
Stuff like LongReadLen might be okay here if and only if changing it just tunes
performance, like you were setting a chunk-buffer size or something, and would
have no impact on behavior nor break any code; otherwise don't have it here.
-- Darren Duncan
More information about the Catalyst
mailing list