NAME Kelp::Module::RDBO - Kelp interface to Rose::DB::Object SYNOPSIS # conf/config.pl { modules => [qw/RDBO/], modules_init => { RDBO => { prefix => 'MyApp::DB', default_type => 'main', source => [ { type => 'main', driver => 'mysql', ... } ], }, } } # lib/MyApp.pm ... sub get_song { my ( $self, $song_id ) = @_; $self->rdb->do_transaction( ... ) my $song = $self->rdbo('Song')->new( id => $song_id )->load; } DESCRIPTION This Kelp module creates a Rose::DB connection at application startup, provides an interface to it, and uses it behind the scenes to pass it to all Rose::DB::Object derived objects. This way, the application developer doesn't have to worry about passing a database object to each new RDBO instance. REGISTERED METHODS This module registers the following methods into your application: rdb A reference to an initialized Rose::DB database object. $self->rdb->do_transaction(sub{ ... }); rdbo A helper method, which prepares and returns a Rose::DB::Object child class. get '/author/:id' => sub { my ( $self, $author_id ) = @_; my $author = $self->rdbo('Author')->new( id => $author_id )->load; return $author->as_tree; }; Under the hood, the "rdbo" method looks for "MyApp::DB::Author", assuming that the name of your application is "MyApp". A different prefix may be specified via the "prefix" configuration option. Then, the module is loaded, and if it does not have its own "init_db" method, one is injected into it, containing the already initialized "Rose::DB" object. To understand the full benefit of this method, one should first make themselves familiar with how RDBO objects are initialized. The RDBO docs provide several ways to do that. One of them is to pass a "db" parameter to each constructor. my $item = MyDB::Item->new( db => ... ); If the "db" parameter is missing, RDBO will look for an "init_db" method. The "rdbo" method described here initializes that behind the scenes, so you don't have to worry about any of the above. CONFIGURATION The configuration of this module is very robust, and as such it may seem a bit complicated in the beginning. Here is a list of all keys used: source Source is a hashref or an array of hashrefs, containing arguments for the "register_db" in Rose::DB method. To give you an example, directly copied from the RDB docs: modules_init => { RDBO => { source => [ { domain => 'development', type => 'main', driver => 'Pg', database => 'dev_db', host => 'localhost', username => 'devuser', password => 'mysecret', server_time_zone => 'UTC', }, { domain => 'production', type => 'main', driver => 'Pg', database => 'big_db', host => 'dbserver.acme.com', username => 'dbadmin', password => 'prodsecret', server_time_zone => 'UTC', } ] } } If you only have a single source, you may use a hashref as the "source" value. default_type Specifies a value for "default_type" in Rose::DB. default_domain Specifies a value for "default_domain" in Rose::DB. modules_init => { RDBO => { default_type => 'main', default_domain => 'development' } }; prefix Specifies the prefix for your RDBO classes. If missing, it will use the name of your application class, plus "::DB". For example, if your app class is called "MyApp", then the default prefix will be "MyApp::DB". modules_init => { RDBO => { prefix => 'RDBO::Nest' } }; # This will look for RDBO::Nest::Song now $self->rdbo('Song')->new; preload Setting this option to a non-zero value will cause the module to load all RDBO classes under the specified "prefix" at startup. It is advised that you have this option on in your deployment config. Preloading all modules may cause a noticeable delay after restarting the web application. If you are impatient and dislike waiting for your application to restart (like the author of this module), you are advised to set this option to a false value in your development config. LINK BACK TO APP This module injects a new method "app" into "Rose::DB::Object", making it available to all deriving classes. This method is a reference to the application instance, and it can be accessed by all object classes that inherit from "Rose::DB::Object". A typical example of when this is useful is when you want to use other modules initialized by your app inside an object class. The following example uses the Kelp::Module::Bcrypt module to bcrypt the user password: package MyApp::DB::User; __PACKAGE__->meta->setup( table => 'users', auto => 1, ); # Add a triger to column 'password' to bcrypt it when it's being set. __PACKAGE__->meta->column('password')->add_trigger( on_set => sub { my $self = shift; $self->password( $self->app->bcrypt( $self->password ) ); } ); AUTHOR Stefan G. minimal cpan.org SEE ALSO Kelp, Rose::DB, Rose::DB::Object LICENSE Perl