The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
NAME

    POE::Component::SimpleDBI - Asynchronous non-blocking DBI calls in POE
    made simple

VERSION

      This document describes v1.31 of POE::Component::SimpleDBI - released November 05, 2014 as part of POE-Component-SimpleDBI.

SYNOPSIS

            use POE;
            use POE::Component::SimpleDBI;
    
            # Create a new session with the alias we want
            POE::Component::SimpleDBI->new( 'SimpleDBI' ) or die 'Unable to create the DBI session';
    
            # Create our own session to communicate with SimpleDBI
            POE::Session->create(
                    inline_states => {
                            _start => sub {
                                    # Tell SimpleDBI to connect
                                    $_[KERNEL]->post( 'SimpleDBI', 'CONNECT',
                                            'DSN'           =>      'DBI:mysql:database=foobaz;host=192.168.1.100;port=3306',
                                            'USERNAME'      =>      'FooBar',
                                            'PASSWORD'      =>      'SecretPassword',
                                            'EVENT'         =>      'conn_handler',
                                    );
    
                                    # Execute a query and return number of rows affected
                                    $_[KERNEL]->post( 'SimpleDBI', 'DO',
                                            'SQL'           =>      'DELETE FROM FooTable WHERE ID = ?',
                                            'PLACEHOLDERS'  =>      [ qw( 38 ) ],
                                            'EVENT'         =>      'deleted_handler',
                                            'INSERT_ID'     =>      0,
                                    );
    
                                    # Retrieve one row of information
                                    $_[KERNEL]->post( 'SimpleDBI', 'SINGLE',
                                            'SQL'           =>      'Select * from FooTable LIMIT 1',
                                            'EVENT'         =>      'success_handler',
                                            'BAGGAGE'       =>      'Some Stuff I want to keep!',
                                    );
    
                                    # We want many rows of information + get the query ID so we can delete it later
                                    # Furthermore, disable prepare_cached on this query
                                    my $id = $_[KERNEL]->call( 'SimpleDBI', 'MULTIPLE',
                                            'SQL'           =>      'SELECT foo, baz FROM FooTable2 WHERE id = ?',
                                            'PLACEHOLDERS'  =>      [ qw( 53 ) ],
                                            'EVENT'         =>      'multiple_handler',
                                            'PREPARE_CACHED'=>      0,
                                    );
    
                                    # Quote something and send it to another session
                                    $_[KERNEL]->post( 'SimpleDBI', 'QUOTE',
                                            'SQL'           =>      'foo$*@%%sdkf"""',
                                            'SESSION'       =>      'OtherSession',
                                            'EVENT'         =>      'quote_handler',
                                    );
    
                                    # Changed our mind!
                                    $_[KERNEL]->post( 'SimpleDBI', 'Delete_Query', $id );
    
                                    # 3 ways to shutdown
    
                                    # This will let the existing queries finish, then shutdown
                                    $_[KERNEL]->post( 'SimpleDBI', 'shutdown' );
    
                                    # This will terminate when the event traverses
                                    # POE's queue and arrives at SimpleDBI
                                    $_[KERNEL]->post( 'SimpleDBI', 'shutdown', 'NOW' );
    
                                    # Even QUICKER shutdown :)
                                    $_[KERNEL]->call( 'SimpleDBI', 'shutdown', 'NOW' );
                            },
    
                            # Define your request handlers here
                            'quote_handler' =>      \&FooHandler,
                            # And so on
                    },
            );

DESCRIPTION

    This module simplifies DBI usage in POE's multitasking world.

    This module is a breeze to use, you'll have DBI calls in your POE
    program up and running in only a few seconds of setup.

    This module does what XML::Simple does for the XML world.

    This module works its magic by creating a new session with POE, then
    spawning off a child process to do the "heavy" lifting. That way, your
    main POE process can continue servicing other clients. Queries are put
    into a queue, and processed one at a time.

    The standard way to use this module is to do this:

            use POE;
            use POE::Component::SimpleDBI;
    
            POE::Component::SimpleDBI->new( ... );
    
            POE::Session->create( ... );
    
            POE::Kernel->run();

 Starting SimpleDBI

    To start SimpleDBI, just call it's new method:

            POE::Component::SimpleDBI->new( 'ALIAS' );

    This method will die on error or return success.

    NOTE: The act of starting/stopping SimpleDBI fires off _child events,
    read the POE documentation on what to do with them :)

    This constructor accepts only 3 arguments.

  Alias

    This sets the session alias in POE.

    The default is "SimpleDBI".

  PREPARE_CACHED

    This sets the global PREPARE_CACHED setting. This is a boolean value.

            POE::Component::SimpleDBI->new( 'ALIAS', 0 );

    The default is enabled.

  SYNCHRONOUS_MODE

    This disables the fork() that the subprocess does. Use this only if you
    are having issues with the backend and want to debug the database
    without dealing with multiprocess issues.

            POE::Component::SimpleDBI->new( 'ALIAS', 1, 1 );

    The default is disabled.

 Commands

    There are a few commands you can trigger in SimpleDBI. They are
    triggered via $_[KERNEL]->post( ... );

  ID

    All of the commands except for Delete_Query and shutdown return an id.
    To get them, do this: my $id = $_[KERNEL]->call( 'SimpleDBI', ... );

    Afterwards, the id can be used to delete queries, look at Delete_Query
    for more information.

  Argument errors

    All of the commands validate their arguments, and if an error happens (
    missing argument, etc ), they will do either: - return undef and forget
    that your request even existed - post to the SESSION/EVENT with ERROR
    present in the data NOTE: The data will not have an ID key present

  Explanation of DO/SINGLE/MULTIPLE/QUOTE arguments

    They are passed in via the $_[KERNEL]->post( ... );

    NOTE: Capitalization is very important!

    SQL

      This is the actual SQL line you want SimpleDBI to execute. You can
      put in placeholders, this module supports them.

    PLACEHOLDERS

      This is an array of placeholders.

      You can skip this if your query does not utilize it.

    SESSION

      This is the session that will get the result

      You can skip this, it defaults to the sending session

    EVENT

      This is the event, triggered whenever a query finished.

      It will get a hash in ARG0, consult the specific queries on what you
      will get.

      NOTE: If the key 'ERROR' exists in the hash, then it will contain the
      error string.

    BAGGAGE

      This is a special argument, you can "attach" any kind of baggage to a
      query. The baggage will be kept by SimpleDBI and returned to the
      Event handler intact.

      This is good for storing data associated with a query like a client
      object, etc.

      You can skip this if your query does not utilize it.

    PREPARE_CACHED

      This was added recently, to override SimpleDBI's default behavior of
      using the $dbh->prepare_cached() function. Setting this to false will
      use $dbh->prepare() instead.

      Some users reported problems with PostgreSQL. After investigation,
      this turned out to be some bizarre OID caching issues when the table
      was updated while the connection is alive. The quick work-around is
      to reconnect to the database, but this was not a "sane" solution.

      This is a simple boolean value, and if this argument does not exist,
      SimpleDBI will use the global setting when calling new().

    INSERT_ID

      This was added recently, to override SimpleDBI's default behavior of
      using the $dbh->last_insert_id() function. Setting this to false will
      disable retrieval of this value.

      This is a simple boolean value, and if this argument does not exist,
      SimpleDBI will default to true.

  CONNECT

    This tells SimpleDBI to connect to the database. NOTE: if we are
    already connected, it will be a success ( SimpleDBI will not disconnect
    then connect automatically ). Accepted arguments:

            DSN             ->      The DBI DSN string, consult the DBI docs on what this is
            USERNAME        ->      The username for the connection
            PASSWORD        ->      The password for the connection
            SESSION         ->      The session to send the results
            EVENT           ->      The event to send the results
            NOW             ->      Tells SimpleDBI to bypass the queue and connect NOW!
            CLEAR           ->      Tells SimpleDBI to clear the queue and connect NOW!
            AUTO_COMMIT     ->      The boolean value we will pass to DBI->connect ( defaults to true )
            CACHEDKIDS      ->      Controls the method to cache prepare_cached queries, an arrayref ( defaults to undef )
            BAGGAGE         ->      Any extra data to keep associated with this query ( SimpleDBI will not touch it )

    NOTE: if the DSN/USERNAME/PASSWORD/SESSION/EVENT does not exist,
    SimpleDBI assumes you wanted to use the old connection and will use the
    cached values ( if you told it to DISCONNECT ). Here's an example on
    how to trigger this event:

            $_[KERNEL]->post( 'SimpleDBI', 'CONNECT',
                    'DSN'           =>      'DBI:mysql:database=foobaz;host=192.168.1.100;port=3306',
                    'USERNAME'      =>      'MyUser',
                    'PASSWORD'      =>      'MyPassword',
                    'EVENT'         =>      'conn_handler',
                    'NOW'           =>      1,
            );

    The NOW/CLEAR arguments are special, they will tell SimpleDBI to bypass
    the request queue and connect NOW... The CLEAR argument will also
    delete all the requests waiting in the queue, they will get an ERROR
    result. They both default to false, supply a boolean value to turn them
    on. The Event handler will get a hash in ARG0:

            {
                    'ERROR'         =>      exists only if an error occured
                    'GONE'          =>      exists only if the server was disconnected and the reconnect failed
                    'ACTION'        =>      'CONNECT'
                    'ID'            =>      ID of the Query
                    'EVENT'         =>      The event the query will respond to
                    'SESSION'       =>      The session the query will respond to
            }
    
            # NOTE: You can do nifty things like this. They all will be executed in the right order!
            $_[KERNEL]->post( 'SimpleDBI', 'CONNECT', 'DSN' => 'DBI:mysql:...', ... );
            $_[KERNEL]->post( 'SimpleDBI', 'DO', ... );
            $_[KERNEL]->post( 'SimpleDBI', 'SINGLE', ... );
            $_[KERNEL]->post( 'SimpleDBI', 'DISCONNECT' );
            $_[KERNEL]->post( 'SimpleDBI', 'CONNECT', 'DSN' => 'DBI:oracle:...', ... );
            $_[KERNEL]->post( 'SimpleDBI', 'MULTIPLE', ... );
            $_[KERNEL]->post( 'SimpleDBI', 'shutdown' );

    As of 1.11 SimpleDBI now detects whether the backend lost the
    connection to the database server. The backend will automatically
    reconnect if it happens, but if that fails, an error will be sent to
    the session/event specified here with an extra key: 'GONE'. In this
    state SimpleDBI is deadlocked, any new queries will not be processed
    until a CONNECT NOW event is issued! Keep in mind the SINGLE/etc
    queries WILL NOT receive an error if this happens, the error goes
    straight to the CONNECT handler to keep it simple!

    As of 1.29 SimpleDBI added better control of the prepare_cached cache.
    Some users reported that the subprocess' memory usage was leaking, and
    in extreme cases reached several gigs! Upon investigation, it was not
    SimpleDBI's fault but the way DBI works. What DBI does is cache the
    statement handle from $dbh->prepare_cached in the $dbh handle. The
    problem is that it stays around forever in the default implementation!
    Perusing the DBI docs revealed that it was possible to tie this cache
    to a custom cache module. So I've added the CACHEDKIDS argument, and
    setting it to an arrayref will enable the behavior. Look at
    http://search.cpan.org/dist/DBI/DBI.pm#prepare_cached for more
    information. Here's an example:

            $_[KERNEL]->post( 'SimpleDBI', 'CONNECT', ..., 'CACHEDKIDS' => [ 'Tie::Cache::LRU' ] );

    The first element in the array is the module to use when tying the
    cache. Any additional elements are passed to the module's constructor.
    Please look at the docs for your favorite cache module! If users report
    success with this, in a future version of SimpleDBI it might become the
    default behavior. Keep in mind that this will be redundant if
    PREPARE_CACHED == 0.

  DISCONNECT

    This tells SimpleDBI to disconnect from the database. NOTE: In the case
    that a DISCONNECT is issued when we are not connected, it will still
    succeed! Accepted arguments:

            SESSION         ->      The session to send the results
            EVENT           ->      The event to send the results
            NOW             ->      Tells SimpleDBI to bypass the queue and disconnect NOW!
            CLEAR           ->      Tells SimpleDBI to clear the queue and disconnect NOW!
            BAGGAGE         ->      Any extra data to keep associated with this query ( SimpleDBI will not touch it )

    Here's an example on how to trigger this event:

            $_[KERNEL]->post( 'SimpleDBI', 'DISCONNECT',
                    'EVENT'         =>      'disconn_handler',
                    'NOW'           =>      1,
            );

    The NOW/CLEAR arguments are special, they will tell SimpleDBI to bypass
    the request queue and connect NOW. The CLEAR argument will also delete
    all the requests waiting in the queue, they will get an ERROR result.
    They both default to false, supply a boolean value to turn them on. The
    Event handler will get a hash in ARG0:

            {
                    'ERROR'         =>      exists only if an error occured
                    'ACTION'        =>      'DISCONNECT'
                    'ID'            =>      ID of the Query
                    'EVENT'         =>      The event the query will respond to
                    'SESSION'       =>      The session the query will respond to
            }
    
            # BEWARE: There is the possibility of a deadlock! In this case, the DO/SINGLE queries will
            # NEVER run until you issue a CONNECT with NOW enabled at the end!
            $_[KERNEL]->post( 'SimpleDBI', 'CONNECT', ... );
            $_[KERNEL]->post( 'SimpleDBI', 'MULTIPLE', ... );
            $_[KERNEL]->post( 'SimpleDBI', 'DISCONNECT' );
            $_[KERNEL]->post( 'SimpleDBI', 'DO', ... );
            $_[KERNEL]->post( 'SimpleDBI', 'SINGLE', ... );
            $_[KERNEL]->post( 'SimpleDBI', 'CONNECT' );

  QUOTE

    This simply sends off a string to be quoted, and gets it back. Accepted
    arguments:

            SESSION         ->      The session to send the results
            EVENT           ->      The event to send the results
            SQL             ->      The string to be quoted
            BAGGAGE         ->      Any extra data to keep associated with this query ( SimpleDBI will not touch it )

    Internally, it does something like this:

            return $dbh->quote( $SQL );

    Here's an example on how to trigger this event:

            $_[KERNEL]->post( 'SimpleDBI', 'QUOTE',
                    SQL => 'foo$*@%%sdkf"""',
                    EVENT => 'quote_handler',
            );

    The Event handler will get a hash in ARG0:

            {
                    'ERROR'         =>      exists only if an error occured
                    'ACTION'        =>      'QUOTE'
                    'ID'            =>      ID of the Query
                    'EVENT'         =>      The event the query will respond to
                    'SESSION'       =>      The session the query will respond to
                    'SQL'           =>      Original SQL inputted
                    'RESULT'        =>      The quoted SQL
                    'PLACEHOLDERS'  =>      Original placeholders ( may not exist if it was not provided )
                    'BAGGAGE'       =>      whatever you set it to ( may not exist if it was not provided )
            }

  DO

    This query is specialized for those queries where you
    UPDATE/DELETE/INSERT/etc. THIS IS NOT FOR SELECT QUERIES! Accepted
    arguments:

            SESSION         ->      The session to send the results
            EVENT           ->      The event to send the results
            SQL             ->      The string to be quoted
            PLACEHOLDERS    ->      Any placeholders ( if needed )
            BAGGAGE         ->      Any extra data to keep associated with this query ( SimpleDBI will not touch it )
            PREPARE_CACHED  ->      Boolean value ( if needed )
            INSERT_ID       ->      Boolean value ( if needed )

    Internally, it does something like this:

            $sth = $dbh->prepare_cached( $SQL );
            $rows_affected = $sth->execute( $PLACEHOLDERS );
            return $rows_affected;

    Here's an example on how to trigger this event:

            $_[KERNEL]->post( 'SimpleDBI', 'DO',
                    SQL => 'DELETE FROM FooTable WHERE ID = ?',
                    PLACEHOLDERS => [ 38 ],
                    EVENT => 'deleted_handler',
            );

    The Event handler will get a hash in ARG0:

            {
                    'ERROR'         =>      exists only if an error occured
                    'ACTION'        =>      'DO'
                    'ID'            =>      ID of the Query
                    'EVENT'         =>      The event the query will respond to
                    'SESSION'       =>      The session the query will respond to
                    'SQL'           =>      Original SQL inputted
                    'RESULT'        =>      Scalar value of rows affected
                    'PLACEHOLDERS'  =>      Original placeholders ( may not exist if it was not provided )
                    'BAGGAGE'       =>      whatever you set it to ( may not exist if it was not provided )
                    'INSERTID'      =>      The insert ID - using $dbh->last_insert_id( undef, undef, undef, undef ) [ defaults to undef ]
            }

  SINGLE

    This query is specialized for those queries where you will get exactly
    1 result back. Accepted arguments:

            SESSION         ->      The session to send the results
            EVENT           ->      The event to send the results
            SQL             ->      The string to be quoted
            PLACEHOLDERS    ->      Any placeholders ( if needed )
            BAGGAGE         ->      Any extra data to keep associated with this query ( SimpleDBI will not touch it )
            PREPARE_CACHED  ->      Boolean value ( if needed )

    Internally, it does something like this:

            $sth = $dbh->prepare_cached( $SQL );
            $sth->execute( $PLACEHOLDERS );
            $result = $sth->fetchrow_hashref;
            return $result;

    Here's an example on how to trigger this event:

            $_[KERNEL]->post( 'SimpleDBI', 'SINGLE',
                    SQL => 'Select * from FooTable',
                    EVENT => 'success_handler',
                    SESSION => 'MySession',
            );

    The Event handler will get a hash in ARG0:

            {
                    'ERROR'         =>      exists only if an error occured
                    'ACTION'        =>      'SINGLE'
                    'ID'            =>      ID of the Query
                    'EVENT'         =>      The event the query will respond to
                    'SESSION'       =>      The session the query will respond to
                    'SQL'           =>      Original SQL inputted
                    'RESULT'        =>      Hash of columns - similar to fetchrow_hashref ( undef if no rows returned )
                    'PLACEHOLDERS'  =>      Original placeholders ( may not exist if it was not provided )
                    'BAGGAGE'       =>      whatever you set it to ( may not exist if it was not provided )
            }

  MULTIPLE

    This query is specialized for those queries where you will get more
    than 1 result back.

    WARNING! The column names are all lowercased automatically! WARNING!

    Accepted arguments:

            SESSION         ->      The session to send the results
            EVENT           ->      The event to send the results
            SQL             ->      The string to be quoted
            PLACEHOLDERS    ->      Any placeholders ( if needed )
            BAGGAGE         ->      Any extra data to keep associated with this query ( SimpleDBI will not touch it )
            PREPARE_CACHED  ->      Boolean value ( if needed )

    Internally, it does something like this:

            $sth = $dbh->prepare_cached( $SQL );
            $sth->execute( $PLACEHOLDERS );
            $sth->bind_columns( \( @$newdata{ @{ $sth->{'NAME_lc'} } } ) );
            while ( $sth->fetch() ) {
                    push( @results, { @$newdata } );
            }
            return \@results;

    Here's an example on how to trigger this event:

            $_[KERNEL]->post( 'SimpleDBI', 'MULTIPLE',
                    SQL => 'SELECT foo, baz FROM FooTable2 WHERE id = ?',
                    EVENT => 'multiple_handler',
                    PLACEHOLDERS => [ 53 ],
                    PREPARE_CACHED => 0,
            );

    The Event handler will get a hash in ARG0:

            {
                    'ERROR'         =>      exists only if an error occured
                    'ACTION'        =>      'MULTIPLE'
                    'ID'            =>      ID of the Query
                    'EVENT'         =>      The event the query will respond to
                    'SESSION'       =>      The session the query will respond to
                    'SQL'           =>      Original SQL inputted
                    'RESULT'        =>      Array of hash of columns - similar to array of fetchrow_hashref's ( undef if no rows returned )
                    'PLACEHOLDERS'  =>      Original placeholders ( may not exist if it was not provided )
                    'BAGGAGE'       =>      whatever you set it to ( may not exist if it was not provided )
            }

  ATOMIC

    This query is specialized for those queries that you need to execute in
    a transaction. You supply an array of SQL queries, and SimpleDBI will
    execute them all in a transaction block. No need to worry about
    AutoCommit, BEGIN, and END TRANSACTION!

    You are supposed to pass an array of queries that normally would be
    executed in a DO-style query. Again, you cannot execute SELECT queries
    in this type of command! Currently there is no control over
    prepare_cached for individual queries. It may be added in a future
    release.

    WARNING: It tripped me up on my testing when I realized this worked on
    Postgres but not MySQL. I forgot that I was testing against MyISAM
    tables, which doesn't support transactions! ( it works nicely on InnoDB
    tables hah ) So, if this doesn't "behave" properly for you please check
    your database tables! Accepted arguments:

            SESSION         ->      The session to send the results
            EVENT           ->      The event to send the results
            SQL             ->      The array of SQL queries
            PLACEHOLDERS    ->      The array of placeholders ( if needed ) [ this is an AoA - array of arrays! ]
            BAGGAGE         ->      Any extra data to keep associated with this query ( SimpleDBI will not touch it )
            PREPARE_CACHED  ->      Boolean value ( if needed ) [ for all of the queries! ]

    Internally, it does something like this:

            eval {
                    $dbh->begin_work;
                    for my $idx ( 0 .. $#array ) {
                            if ( $prepare_cached ) {
                                    $sth = $dbh->prepare_cached( $array[ $idx ] );
                            } else {
                                    $sth = $dbh->prepare( $array[ $idx ] );
                            }
                            if ( defined $PLACEHOLDERS[ $idx ] ) {
                                    $sth->execute( $PLACEHOLDERS[ $idx ] );
                            } else {
                                    $sth->execute;
                            }
                            $sth->finish;
                    }
                    $dbh->commit;
            };
            if ( $@ ) {
                    eval { $dbh->rollback };
                    if ( $@ ) {
                            return ROLLBACK_FAILURE;
                    } else {
                            return COMMIT_FAILURE;
                    }
            } else {
                    return SUCCESS;
            }

    Here's an example on how to trigger this event:

            $_[KERNEL]->post( 'SimpleDBI', 'ATOMIC',
                    SQL => [
                            'DELETE FROM FooTable WHERE ID = ?',
                            'UPDATE FooTable SET baz = ? WHERE bar = ?',
                    ],
                    EVENT => 'atomic_handler',
                    PLACEHOLDERS => [       [ 53 ],
                                            [ 5, 86 ]
                    ],
            );

    The Event handler will get a hash in ARG0:

            {
                    'ERROR'         =>      exists only if an error occured ( ROLLBACK_FAILURE or COMMIT_FAILURE with explanation )
                    'ACTION'        =>      'ATOMIC'
                    'ID'            =>      ID of the Query
                    'EVENT'         =>      The event the query will respond to
                    'SESSION'       =>      The session the query will respond to
                    'SQL'           =>      Original SQL array inputted
                    'RESULT'        =>      Either SUCCESS or in case of error, not exists
                    'PLACEHOLDERS'  =>      Original placeholders ( may not exist if it was not provided )
                    'BAGGAGE'       =>      whatever you set it to ( may not exist if it was not provided )
            }

  Delete_Query

    Call this event if you want to delete a query via the ID. Returns:

            undef if it wasn't able to find the ID
            0 if the query is currently being processed
            1 if the query was successfully deleted

    Here's an example on how to trigger this event:

            $_[KERNEL]->post( 'SimpleDBI', 'Delete_Query', $queryID );

    IF you really want to know the status, execute a call on the event and
    check the returned value.

  Clear_Queue

    This event will clear the entire queue except the running query, if
    there is one.

    You can also pass in one argument -> the error string to be used
    instead of the default, 'Cleared the queue'

    All the queries in the queue will return ERROR to their respective
    sessions/events

  shutdown

    This will signal SimpleDBI to start the shutdown procedure. Without
    arguments, SimpleDBI will wait for outstanding queries to complete
    before killing it's session. You can also specify an argument to ignore
    those queries and immediately halt:

            $_[KERNEL]->post( 'SimpleDBI', 'shutdown', 'NOW' );

    Due to the way POE's queue works, this shutdown event will take some
    time to propagate POE's queue. If you REALLY want to shut down
    immediately, do this:

            $_[KERNEL]->call( 'SimpleDBI', 'shutdown', 'NOW' );

 SimpleDBI Notes

    This module is very picky about capitalization!

    All of the options are uppercase, to avoid confusion.

    You can enable debugging mode by doing this:

            sub POE::Component::SimpleDBI::DEBUG () { 1 }
            use POE::Component::SimpleDBI;

    Also, this module will try to keep the SubProcess alive. if it dies, it
    will open it again for a max of 5 retries.

    You can override this behavior by doing this:

            sub POE::Component::SimpleDBI::MAX_RETRIES () { 10 }
            use POE::Component::SimpleDBI;

  DBI attributes

    Since SimpleDBI doesn't expose the DBI handle it might be an issue if
    you need to set custom attributes. Fear not for DBI already has a
    standard mechanism for this: "connection attribute values" in
    "#connect" in DBI. Here is an example to enable utf8 for a Postgres
    database:

            $_[KERNEL]->post( 'SimpleDBI', 'CONNECT',
                    'DSN'           =>      'DBI:Pg(pg_enable_utf8=>1):host=foo;dbname=bar',
                    ...
            );

SEE ALSO

    Please see those modules/websites for more information related to this
    module.

      * DBI

      * POE::Component::DBIAgent

      * POE::Component::LaDBI

      * POE::Component::EasyDBI

SUPPORT

 Perldoc

    You can find documentation for this module with the perldoc command.

      perldoc POE::Component::SimpleDBI

 Websites

    The following websites have more information about this module, and may
    be of help to you. As always, in addition to those websites please use
    your favorite search engine to discover more resources.

      * MetaCPAN

      A modern, open-source CPAN search engine, useful to view POD in HTML
      format.

      http://metacpan.org/release/POE-Component-SimpleDBI

      * Search CPAN

      The default CPAN search engine, useful to view POD in HTML format.

      http://search.cpan.org/dist/POE-Component-SimpleDBI

      * RT: CPAN's Bug Tracker

      The RT ( Request Tracker ) website is the default bug/issue tracking
      system for CPAN.

      http://rt.cpan.org/NoAuth/Bugs.html?Dist=POE-Component-SimpleDBI

      * AnnoCPAN

      The AnnoCPAN is a website that allows community annotations of Perl
      module documentation.

      http://annocpan.org/dist/POE-Component-SimpleDBI

      * CPAN Ratings

      The CPAN Ratings is a website that allows community ratings and
      reviews of Perl modules.

      http://cpanratings.perl.org/d/POE-Component-SimpleDBI

      * CPAN Forum

      The CPAN Forum is a web forum for discussing Perl modules.

      http://cpanforum.com/dist/POE-Component-SimpleDBI

      * CPANTS

      The CPANTS is a website that analyzes the Kwalitee ( code metrics )
      of a distribution.

      http://cpants.cpanauthors.org/dist/overview/POE-Component-SimpleDBI

      * CPAN Testers

      The CPAN Testers is a network of smokers who run automated tests on
      uploaded CPAN distributions.

      http://www.cpantesters.org/distro/P/POE-Component-SimpleDBI

      * CPAN Testers Matrix

      The CPAN Testers Matrix is a website that provides a visual overview
      of the test results for a distribution on various Perls/platforms.

      http://matrix.cpantesters.org/?dist=POE-Component-SimpleDBI

      * CPAN Testers Dependencies

      The CPAN Testers Dependencies is a website that shows a chart of the
      test results of all dependencies for a distribution.

      http://deps.cpantesters.org/?module=POE::Component::SimpleDBI

 Email

    You can email the author of this module at APOCAL at cpan.org asking
    for help with any problems you have.

 Internet Relay Chat

    You can get live help by using IRC ( Internet Relay Chat ). If you
    don't know what IRC is, please read this excellent guide:
    http://en.wikipedia.org/wiki/Internet_Relay_Chat. Please be courteous
    and patient when talking to us, as we might be busy or sleeping! You
    can join those networks/channels and get help:

      * irc.perl.org

      You can connect to the server at 'irc.perl.org' and join this
      channel: #perl-help then talk to this person for help: Apocalypse.

      * irc.freenode.net

      You can connect to the server at 'irc.freenode.net' and join this
      channel: #perl then talk to this person for help: Apocal.

      * irc.efnet.org

      You can connect to the server at 'irc.efnet.org' and join this
      channel: #perl then talk to this person for help: Ap0cal.

 Bugs / Feature Requests

    Please report any bugs or feature requests by email to
    bug-poe-component-simpledbi at rt.cpan.org, or through the web
    interface at
    http://rt.cpan.org/NoAuth/ReportBug.html?Queue=POE-Component-SimpleDBI.
    You will be automatically notified of any progress on the request by
    the system.

 Source Code

    The code is open to the world, and available for you to hack on. Please
    feel free to browse it and play with it, or whatever. If you want to
    contribute patches, please send me a diff or prod me to pull from your
    repository :)

    https://github.com/apocalypse/perl-poe-simpledbi

      git clone https://github.com/apocalypse/perl-poe-simpledbi.git

AUTHOR

    Apocalypse <APOCAL@cpan.org>

 CONTRIBUTORS

      * Apocalypse <apoc@blackhole.(none)>

      * Apocalypse <apoc@satellite.(none)>

      * Rocco Caputo <rcaputo@cpan.org>

COPYRIGHT AND LICENSE

    This software is copyright (c) 2014 by Apocalypse.

    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.

    The full text of the license can be found in the LICENSE file included
    with this distribution.

DISCLAIMER OF WARRANTY

    THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
    APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
    HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
    WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
    PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
    OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU
    ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

    IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
    WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR
    CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
    INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
    ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
    NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES
    SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO
    OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY
    HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.