NAME
    Kelp::Module::RDBO - Kelp interface to Rose::DB::Object

SYNOPSIS
        # conf/config.pl
        {
            modules      => [qw/RDBO/],
            modules_init => {
                RDBO => {
                    prefix         => 'MyApp::DB',
                    default_domain => 'development',
                    default_type   => 'main',
                    source         => [
                        {
                            domain => 'development',
                            type   => 'main',
                            driver => 'mysql',
                            ...
                        },
                        {
                            domain => 'development',
                            type   => 'readonly',
                            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 the default Rose::DB database object.

        $self->rdb->do_transaction(sub{ ... });

    To access a database of different type or domain, use parameters:

        my $db = $self->rdb( domain => 'production', type => 'readonly' );
        $db->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.

    To access a database of different type or domain, use parameters:

        my $author = $self->rdbo('Author', type => 'readonly')
                          ->new( id => $author_id )
                          ->load;

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 <at> cpan.org

SEE ALSO
    Kelp, Rose::DB, Rose::DB::Object

LICENSE
    Perl