|
NAMEPOE::Component::EasyDBI - Perl extension for asynchronous non-blocking DBI calls in POE SYNOPSIS use POE qw(Component::EasyDBI);
# Set up the DBI
POE::Component::EasyDBI->spawn( # or new(), witch returns an obj
alias => 'EasyDBI',
dsn => 'DBI:mysql:database=foobaz;host=192.168.1.100;port=3306',
username => 'user',
password => 'pass',
options => {
AutoCommit => 0,
},
);
# Create our own session to communicate with EasyDBI
POE::Session->create(
inline_states => {
_start => sub {
$_[KERNEL]->post('EasyDBI',
do => {
sql => 'CREATE TABLE users (id INT, username VARCHAR(100))',
event => 'table_created',
}
);
},
table_created => sub {
$_[KERNEL]->post('EasyDBI',
insert => {
# multiple inserts
insert => [
{ id => 1, username => 'foo' },
{ id => 2, username => 'bar' },
{ id => 3, username => 'baz' },
],
table => 'users',
event => 'done',
},
);
$_[KERNEL]->post('EasyDBI',
commit => {
event => 'done'
}
);
$_[KERNEL]->post('EasyDBI' => 'shutdown');
},
done => sub {
my $result = $_[ARG0];
}
},
);
POE::Kernel->run();
ABSTRACT This module simplifies DBI usage in POE's multitasking world.
This module is easy to use, you'll have DBI calls in your POE program
up and running in no time.
It also works in Windows environments!
DESCRIPTIONThis module works by creating a new session, then spawning a child process to do the DBI queries. That way, your main POE process can continue servicing other clients. The standard way to use this module is to do this: use POE;
use POE::Component::EasyDBI;
POE::Component::EasyDBI->spawn(...);
POE::Session->create(...);
POE::Kernel->run();
Starting EasyDBITo start EasyDBI, just call it's spawn method. (or new for an obj) This one is for Postgresql: POE::Component::EasyDBI->spawn(
alias => 'EasyDBI',
dsn => 'DBI:Pg:dbname=test;host=10.0.1.20',
username => 'user',
password => 'pass',
);
This one is for mysql: POE::Component::EasyDBI->spawn(
alias => 'EasyDBI',
dsn => 'DBI:mysql:database=foobaz;host=192.168.1.100;port=3306',
username => 'user',
password => 'pass',
);
This method will die on error or return success. Note the difference between dbname and database, that is dependant on the driver used, NOT EasyDBI NOTE: If the SubProcess could not connect to the DB, it will return an error, causing EasyDBI to croak/die. NOTE: Starting with version .10, I've changed new() to return a EasyDBI object and spawn() returns a session reference. Also, create() is the same as spawn(). See "OBJECT METHODS". This constructor accepts 6 different options.
EventsThere is only a few events you can trigger in EasyDBI. They all share a common argument format, except for the shutdown event. Note: you can change the session that the query posts back to, it uses $_[SENDER] as the default. You can use a postback, or callback (See POE::Session) For example: $kernel->post('EasyDBI',
quote => {
sql => 'foo$*@%%sdkf"""',
event => 'quoted_handler',
session => 'dbi_helper', # or session id
}
);
or $kernel->post('EasyDBI',
quote => {
sql => 'foo$*@%%sdkf"""',
event => $_[SESSION]->postback("quoted_handler"),
session => 'dbi_helper', # or session id
}
);
Arguments They are passed in via the $kernel->post(...); Note: all query types can be in ALL-CAPS or lowercase but not MiXeD! ie ARRAYHASH or arrayhash but not ArrayHash
OBJECT METHODSWhen using new() to spawn/create the EasyDBI object, you can use the methods listed below NOTE: The object interface will be improved in later versions, please send suggestions to the author.
LONG EXAMPLE use POE qw(Component::EasyDBI);
# Set up the DBI
POE::Component::EasyDBI->spawn(
alias => 'EasyDBI',
dsn => 'DBI:mysql:database=foobaz;host=192.168.1.100;port=3306',
username => 'user',
password => 'pass',
);
# Create our own session to communicate with EasyDBI
POE::Session->create(
inline_states => {
_start => sub {
$_[KERNEL]->post('EasyDBI',
do => {
sql => 'DELETE FROM users WHERE user_id = ?',
placeholders => [qw(144)],
event => 'deleted_handler',
}
);
# 'single' is very different from the single query in SimpleDBI
# look at 'hash' to get those results
# If you select more than one field, you will only get the last one
# unless you pass in a separator with what you want the fields seperated by
# to get null sperated values, pass in separator => "\0"
$_[KERNEL]->post('EasyDBI',
single => {
sql => 'Select user_id,user_login from users where user_id = ?',
event => 'single_handler',
placeholders => [qw(144)],
separator => ',', #optional!
}
);
$_[KERNEL]->post('EasyDBI',
quote => {
sql => 'foo$*@%%sdkf"""',
event => 'quote_handler',
}
);
$_[KERNEL]->post('EasyDBI',
arrayhash => {
sql => 'SELECT user_id,user_login from users where logins = ?',
event => 'arrayash_handler',
placeholders => [qw(53)],
}
);
my $postback = $_[SESSION]->postback("arrayhash_handler",3,2,1);
$_[KERNEL]->post('EasyDBI',
arrayhash => {
sql => 'SELECT user_id,user_login from users',
event => $postback,
}
);
$_[KERNEL]->post('EasyDBI',
arrayarray => {
sql => 'SELECT * from locations',
event => 'arrayarray_handler',
primary_key => '1', # you can specify a primary key, or a number based on what column to use
}
);
$_[KERNEL]->post('EasyDBI',
hashhash => {
sql => 'SELECT * from locations',
event => 'hashhash_handler',
primary_key => '1', # you can specify a primary key, or a number based on what column to use
}
);
$_[KERNEL]->post('EasyDBI',
hasharray => {
sql => 'SELECT * from locations',
event => 'hasharray_handler',
primary_key => "1",
}
);
# you should use limit 1, it is NOT automaticly added
$_[KERNEL]->post('EasyDBI',
hash => {
sql => 'SELECT * from locations LIMIT 1',
event => 'hash_handler',
}
);
$_[KERNEL]->post('EasyDBI',
array => {
sql => 'SELECT location_id from locations',
event => 'array_handler',
}
);
$_[KERNEL]->post('EasyDBI',
keyvalhash => {
sql => 'SELECT location_id,location_name from locations',
event => 'keyvalhash_handler',
# if primary_key isn't used, the first one is assumed
}
);
$_[KERNEL]->post('EasyDBI',
insert => {
sql => 'INSERT INTO zipcodes (zip,city,state) VALUES (?,?,?)',
placeholders => ['98004', 'Bellevue', 'WA'],
event => 'insert_handler',
}
);
$_[KERNEL]->post('EasyDBI',
insert => {
# this can also be a array of hashes similar to this
hash => { username => 'test' , pass => 'sUpErSeCrEt', name => 'John' },
table => 'users',
last_insert_id => {
field => 'user_id', # mysql uses SELECT LAST_INSERT_ID instead
table => 'users', # of these values, just specify {} for mysql
},
event => 'insert_handler',
# or last_insert_id can be => 'SELECT LAST_INSERT_ID()' or some other
# query that will return a value
},
);
# 3 ways to shutdown
# This will let the existing queries finish, then shutdown
$_[KERNEL]->post('EasyDBI', 'shutdown');
# This will terminate when the event traverses
# POE's queue and arrives at EasyDBI
#$_[KERNEL]->post('EasyDBI', shutdown => 'NOW');
# Even QUICKER shutdown :)
#$_[KERNEL]->call('EasyDBI', shutdown => 'NOW');
},
deleted_handler => \&deleted_handler,
quote_handler => \"e_handler,
arrayhash_handler => \&arrayhash_handler,
},
);
sub quote_handler {
# For QUOTE calls, we receive the scalar string of SQL quoted
# $_[ARG0] = {
# sql => The SQL you sent
# result => scalar quoted SQL
# placeholders => The placeholders
# action => 'QUOTE'
# error => Error occurred, check this first
# }
}
sub deleted_handler {
# For DO calls, we receive the scalar value of rows affected
# $_[ARG0] = {
# sql => The SQL you sent
# result => scalar value of rows affected
# placeholders => The placeholders
# action => 'do'
# error => Error occurred, check this first
# }
}
sub single_handler {
# For SINGLE calls, we receive a scalar
# $_[ARG0] = {
# sql => The SQL you sent
# result => scalar
# placeholders => The placeholders
# action => 'single'
# separator => Seperator you may have sent
# error => Error occurred, check this first
# }
}
sub arrayhash_handler {
# For arrayhash calls, we receive an array of hashes
# $_[ARG0] = {
# sql => The SQL you sent
# result => array of hash refs
# placeholders => The placeholders
# action => 'arrayhash'
# error => Error occurred, check this first
# }
}
sub hashhash_handler {
# For hashhash calls, we receive a hash of hashes
# $_[ARG0] = {
# sql => The SQL you sent
# result => hash ref of hash refs keyed on primary key
# placeholders => The placeholders
# action => 'hashhash'
# cols => array of columns in order (to help recreate the sql order)
# primary_key => column you specified as primary key, if you specifed
# a number, the real column name will be here
# error => Error occurred, check this first
# }
}
sub hasharray_handler {
# For hasharray calls, we receive an hash of arrays
# $_[ARG0] = {
# sql => The SQL you sent
# result => hash ref of array refs keyed on primary key
# placeholders => The placeholders
# action => 'hashhash'
# cols => array of columns in order (to help recreate the sql order)
# primary_key => column you specified as primary key, if you specifed
# a number, the real column name will be here
# error => Error occurred, check this first
# }
}
sub array_handler {
# For array calls, we receive an array
# $_[ARG0] = {
# sql => The SQL you sent
# result => an array, if multiple fields are used, they are comma
# seperated (specify separator in event call to change this)
# placeholders => The placeholders
# action => 'array'
# separator => you sent # optional!
# error => Error occurred, check this first
# }
}
sub arrayarray_handler {
# For array calls, we receive an array ref of array refs
# $_[ARG0] = {
# sql => The SQL you sent
# result => an array ref of array refs
# placeholders => The placeholders
# action => 'arrayarray'
# error => Error occurred, check this first
# }
}
sub hash_handler {
# For hash calls, we receive a hash
# $_[ARG0] = {
# sql => The SQL you sent
# result => a hash
# placeholders => The placeholders
# action => 'hash'
# error => Error occurred, check this first
# }
}
sub keyvalhash_handler {
# For keyvalhash calls, we receive a hash
# $_[ARG0] = {
# sql => The SQL you sent
# result => a hash # first field is the key, second is the value
# placeholders => The placeholders
# action => 'keyvalhash'
# error => Error occurred, check this first
# primary_key => primary key used
# }
}
sub insert_handle {
# $_[ARG0] = {
# sql => The SQL you sent
# placeholders => The placeholders
# action => 'insert'
# table => 'users',
# # for postgresql, or others?
# last_insert_id => { # used to retrieve the insert id of the inserted row
# field => The field of id requested
# table => The table the holds the field
# },
# -OR-
# last_insert_id => 'SELECT LAST_INSERT_ID()', # mysql style
# result => the id from the last_insert_id post query
# error => Error occurred, check this first
# }
}
EasyDBI NotesThis module is very picky about capitalization! All of the options are in lowercase. Query types can be in ALL-CAPS or lowercase. This module will try to keep the SubProcess alive. if it dies, it will open it again for a max of 5 retries by default, but you can override this behavior by using max_retries Please rate this module. <http://cpanratings.perl.org/rate/?distribution=POE-Component-EasyDBI> EXPORTNothing. SEE ALSODBI, POE, POE::Wheel::Run, POE::Component::DBIAgent, POE::Component::LaDBI, POE::Component::SimpleDBI DBD::AnyData, DBD::SQLite AnyEvent::DBI AUTHORDavid Davis <xantus@cpan.org> CREDITS
COPYRIGHT AND LICENSECopyright 2003-2005 by David Davis and Teknikill Software This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
|