1package POE::Component::EasyDBI::SubProcess; 2 3use strict; 4use warnings FATAL => 'all'; 5 6# Initialize our version 7our $VERSION = '1.28'; 8 9use Try::Tiny qw( try catch ); 10 11# We pass in data to POE::Filter::Reference 12use POE::Filter::Reference; 13 14# We run the actual DB connection here 15use DBI; 16 17sub new { 18 my ($class, $opts) = @_; 19 my $obj = bless($opts, $class); 20 $obj->{queue} = []; 21 $obj->{ping_timeout} = $obj->{ping_timeout} || 0; 22 return $obj; 23} 24 25# This is the subroutine that will get executed upon the fork() call by our parent 26sub main { 27 if ( $^O eq 'MSWin32' ) { 28 binmode(STDIN); binmode(STDOUT); 29 } 30 # Autoflush to avoid weirdness 31 #select((select(STDOUT), $| = 1)[0]); 32 select(STDOUT); $|++; 33 select(STDERR); $|++; 34 35 $SIG{__WARN__} = 'DEFAULT'; 36 $SIG{__DIE__} = 'DEFAULT'; 37 38 my $self; 39 # check for alternate fork 40 if ($_[0] == 1) { 41 # we need to read in the first 42 my $filter = POE::Filter::Reference->new(); 43 my $opts; 44 # get our first option hashref 45 while ( sysread( STDIN, my $buffer = '', 1024 ) ) { 46 $opts = $filter->get( [ $buffer ] ); 47 last if (defined $opts); 48 } 49 $self = __PACKAGE__->new(splice(@{$opts},0,1)); 50 $self->{filter} = $filter; 51 if (@{$opts}) { 52 push(@{$self->{queue}},@{$opts}); 53 } 54 undef $filter; 55 } else { 56 $self = __PACKAGE__->new(shift); 57 $self->{filter} = POE::Filter::Reference->new(); 58 } 59 60 $self->{0} = $0 = "$0 ".__PACKAGE__; 61 62 $self->{lastpingtime} = time(); 63 64 unless (defined($self->{sig_ignore_off})) { 65 $SIG{INT} = $SIG{TERM} = $SIG{HUP} = 'IGNORE'; 66 } 67 68# if (defined($self->{use_cancel})) { 69 # Signal INT causes query cancel 70 # XXX disabled for now 71 #$SIG{INT} = sub { if ($sth) { $sth->cancel; } }; 72# } 73 74 while (!$self->connect()) { } 75 76 $self->pt("connected at ".localtime()); 77 78 return if ($self->{done}); 79 80 # check for data in queue first 81 $self->process(); 82 83 if ($self->{done}) { 84 $self->pt("disconnected at ".localtime()); 85 if ($self->{dbh}) { 86 $self->{dbh}->disconnect(); 87 } 88 return; 89 } 90 91 # listen for commands from our parent 92 READ: while ( sysread( STDIN, my $buffer = '', 1024 ) ) { 93 # Feed the line into the filter 94 # and put the data in the queue 95 my $d = $self->{filter}->get( [ $buffer ] ); 96 push(@{$self->{queue}},@$d) if ($d); 97 98 # INPUT STRUCTURE IS: 99 # $d->{action} = SCALAR -> WHAT WE SHOULD DO 100 # $d->{sql} = SCALAR -> THE ACTUAL SQL 101 # $d->{placeholders} = ARRAY -> PLACEHOLDERS WE WILL USE 102 # $d->{id} = SCALAR -> THE QUERY ID ( FOR PARENT TO KEEP TRACK OF WHAT IS WHAT ) 103 # $d->{primary_key} = SCALAR -> PRIMARY KEY FOR A HASH OF HASHES 104 # $d->{last_insert_id} = SCALAR|HASH -> HASH REF OF TABLE AND FIELD OR SCALAR OF A QUERY TO RUN AFTER 105 # and others.. 106 107 # process all in the queue until a problem occurs or done 108 REDO: 109 unless ($self->process()) { 110 last READ if ($self->{done}); 111 # oops problem... 112 if ($self->{reconnect}) { 113 # need to reconnect 114 delete $self->{reconnect}; 115 # keep trying to connect 116 while (!$self->connect()) { } 117 # and bail when we are told 118 last READ if ($self->{done}); 119 goto REDO; 120 } 121 } 122 } 123 # Arrived here due to error in sysread/etc 124 if ($self->{dbh}) { 125 $self->{dbh}->disconnect(); 126 delete $self->{dbh}; 127 } 128 129 # debug 130# require POE::API::Peek; 131# my $p = POE::API::Peek->new(); 132# my @sessions = $p->session_list(); 133# require Data::Dumper; 134# open(FH,">db.txt"); 135# print FH Data::Dumper->Dump([\@sessions]); 136# close(FH); 137} 138 139sub pt { 140 $0 = shift->{0}.' '.shift; 141} 142 143sub connect { 144 my $self = shift; 145 146 $self->{output} = undef; 147 $self->{error} = undef; 148 149 # Actually make the connection 150 try { 151 $self->{dbh} = DBI->connect( 152 # The DSN we just set up 153 (map { $self->{$_} } qw( dsn username password )), 154 155 # We set some configuration stuff here 156 { 157 ((ref($self->{options}) eq 'HASH') ? %{$self->{options}} : ()), 158 159 # quiet!! 160 'PrintError' => 0, 161 'PrintWarn' => 0, 162 163 # Automatically raise errors so we can catch them with try/catch 164 'RaiseError' => 1, 165 166 # Disable the DBI tracing 167 'TraceLevel' => 0, 168 }, 169 ); 170 171 # Check for undefined-ness 172 if (!defined($self->{dbh})) { 173 die "Error Connecting to Database: $DBI::errstr"; 174 } 175 } catch { 176 $self->output( $self->make_error( 'DBI', shift ) ); 177 }; 178 179 # Catch errors! 180 if ($self->{error} && $self->{no_connect_failures}) { 181 sleep($self->{reconnect_wait}) if ($self->{reconnect_wait}); 182 return 0; 183 } elsif ($self->{error}) { 184 # QUIT 185 $self->{done} = 1; 186 return 1; 187 } 188 189# if ($self->{dsn} =~ m/SQLite/ && $self->{options} 190# && ref($self->{options}) eq 'HASH' && $self->{options}->{AutoCommit}) { 191# # TODO error checking 192# $self->db_do({ sql => 'BEGIN', id => -1 }); 193# delete $self->{output}; 194# } 195 196 # send connect notice 197 $self->output({ id => 'DBI-CONNECTED' }); 198 199 return 1; 200} 201 202sub process { 203 my $self = shift; 204 205 return 0 unless (@{$self->{queue}}); 206 207 # Process each data structure 208 foreach my $input (shift(@{$self->{queue}})) { 209 $input->{action} = lc($input->{action}); 210 211 # Now, we do the actual work depending on what kind of query it was 212 if ($input->{action} eq 'exit') { 213 # Disconnect! 214 $self->{done} = 1; 215 return 0; 216 } 217 218 my $now = time(); 219 my $needping = (($self->{ping_timeout} == 0 or $self->{ping_timeout} > 0) 220 and (($now - $self->{lastpingtime}) >= $self->{ping_timeout})) ? 1 : 0; 221 222 if ($self->{dbh}) { 223# Don't work: 224# unless ($self->{dbh}->{Active}) { 225# # put the query back on the stack 226# unshift(@{$self->{queue}},$input); 227# # and reconnect 228# $self->{dbh}->disconnect(); 229# $self->{reconnect} = 1; 230# return 0; 231# } 232 if ($needping) { 233 if (eval{ $self->{dbh}->ping(); }) { 234 $self->pt("pinged at ".localtime()); 235 $self->{lastpingtime} = $now; 236 } else { 237 # put the query back on the stack 238 unshift(@{$self->{queue}},$input); 239 # and reconnect 240 $self->{dbh}->disconnect(); 241 $self->{reconnect} = 1; 242 return 0; 243 } 244 } 245 #} elsif (!$self->{dbh}) { 246 } else { 247 #die "Database gone? : $DBI::errstr"; 248 # put the query back on the stack 249 unshift(@{$self->{queue}},$input); 250 # and reconnect 251 eval { $self->{dbh}->disconnect(); }; 252 $self->{reconnect} = 1; 253 return 0; 254 } 255 256 if (defined($self->{no_cache}) && !defined($input->{no_cache})) { 257 $input->{no_cache} = $self->{no_cache}; 258 } 259 260 if (defined($input->{sql})) { 261 # remove beginning whitespace 262 $input->{sql} =~ s/^\s*//; 263 } 264 265 if ( $input->{action} =~ m/^(func|commit|rollback|begin_work)$/ ) { 266 $input->{method} = $input->{action}; 267 $self->do_method( $input ); 268 } elsif ( $input->{action} eq 'method') { 269 # Special command to do $dbh->$method->() 270 $self->do_method( $input ); 271 } elsif ( $input->{action} eq 'insert' ) { 272 # Fire off the SQL and return success/failure + rows affected and insert id 273 $self->db_insert( $input ); 274 } elsif ( $input->{action} eq 'do' ) { 275 # Fire off the SQL and return success/failure + rows affected 276 $self->db_do( $input ); 277 } elsif ( $input->{action} eq 'single' ) { 278 # Return a single result 279 $self->db_single( $input ); 280 } elsif ( $input->{action} eq 'quote' ) { 281 $self->db_quote( $input ); 282 } elsif ( $input->{action} eq 'arrayhash' ) { 283 # Get many results, then return them all at the same time in a array of hashes 284 $self->db_arrayhash( $input ); 285 } elsif ( $input->{action} eq 'hashhash' ) { 286 # Get many results, then return them all at the same time in a hash of hashes 287 # on a primary key of course. the columns are returned in the cols key 288 $self->db_hashhash( $input ); 289 } elsif ( $input->{action} eq 'hasharray' ) { 290 # Get many results, then return them all at the same time in a hash of arrays 291 # on a primary key of course. the columns are returned in the cols key 292 $self->db_hasharray( $input ); 293 } elsif ( $input->{action} eq 'array' ) { 294 # Get many results, then return them all at the same time in an array of comma seperated values 295 $self->db_array( $input ); 296 } elsif ( $input->{action} eq 'arrayarray' ) { 297 # Get many results, then return them all at the same time in an array of arrays 298 $self->db_arrayarray( $input ); 299 } elsif ( $input->{action} eq 'hash' ) { 300 # Get many results, then return them all at the same time in a hash keyed off the 301 # on a primary key 302 $self->db_hash( $input ); 303 } elsif ( $input->{action} eq 'keyvalhash' ) { 304 # Get many results, then return them all at the same time in a hash with 305 # the first column being the key and the second being the value 306 $self->db_keyvalhash( $input ); 307 } else { 308 # Unrecognized action! 309 $self->{output} = $self->make_error( $input->{id}, "Unknown action sent '$input->{id}'" ); 310 } 311 # XXX another way? 312 if ($input->{id} eq 'DBI' || ($self->{output}->{error} 313 && ($self->{output}->{error} =~ m/no connection to the server/i 314 || $self->{output}->{error} =~ m/server has gone away/i 315 || $self->{output}->{error} =~ m/server closed the connection/i 316 || $self->{output}->{error} =~ m/connect failed/i))) { 317 318 unshift(@{$self->{queue}},$input); 319 eval { $self->{dbh}->disconnect(); }; 320 $self->{reconnect} = 1; 321 return 0; 322 } 323 $self->output; 324 } 325 return 1; 326} 327 328sub commit { 329 my $self = shift; 330 my $id = shift->{id}; 331 try { 332 $self->{dbh}->commit; 333 } catch { 334 $self->{output} = $self->make_error( $id, shift ); 335 }; 336 return ($self->{output}) ? 0 : 1; 337} 338 339sub begin_work { 340 my $self = shift; 341 my $id = shift->{id}; 342 try { 343 $self->{dbh}->begin_work; 344 } catch { 345 $self->{output} = $self->make_error( $id, shift ); 346 }; 347 return ($self->{output}) ? 0 : 1; 348} 349 350# This subroutine makes a generic error structure 351sub make_error { 352 my $self = shift; 353 354 # Make the structure 355 my $data = { id => shift }; 356 357 # Get the error, and stringify it in case of Error::Simple objects 358 my $error = shift; 359 360 if (ref($error) && ref($error) eq 'Error::Simple') { 361 $data->{error} = $error->text; 362 } else { 363 $data->{error} = $error; 364 } 365 366 if ($data->{error} =~ m/has gone away/i || $data->{error} =~ m/lost connection/i) { 367 $data->{id} = 'DBI'; 368 } 369 370 $self->{error} = $data; 371 372 # All done! 373 return $data; 374} 375 376# This subroute is for supporting any type of $dbh->$method->() calls 377sub do_method { 378 # Get the dbi handle 379 my $self = shift; 380 381 # Get the input structure 382 my $data = shift; 383 384 # The result 385 my $result = undef; 386 387 my $method = $data->{method}; 388 my $dbh = $self->{dbh}; 389 390 SWITCH: { 391 392 if ($data->{begin_work}) { 393 $self->begin_work($data) or last SWITCH; 394 } 395 396 # Catch any errors 397 try { 398 if ($data->{args} && ref($data->{args}) eq 'ARRAY') { 399 $result = $dbh->$method(@{$data->{args}}); 400 } else { 401 $result = $dbh->$method(); 402 } 403 404 } catch { 405 $self->{output} = $self->make_error( $data->{id}, shift ); 406 }; 407 408 } 409 410 # Check if we got any errors 411 if (!defined($self->{output})) { 412 # Make output include the results 413 $self->{output} = { result => $result, id => $data->{id} }; 414 } 415 416 return; 417} 418 419# This subroutine does a DB QUOTE 420sub db_quote { 421 my $self = shift; 422 423 # Get the input structure 424 my $data = shift; 425 426 # The result 427 my $quoted = undef; 428 429 # Quote it! 430 try { 431 $quoted = $self->{dbh}->quote( $data->{sql} ); 432 } catch { 433 $self->{output} = $self->make_error( $data->{id}, shift ); 434 }; 435 436 # Check for errors 437 if (!defined($self->{output})) { 438 # Make output include the results 439 $self->{output} = { result => $quoted, id => $data->{id} }; 440 } 441 return; 442} 443 444# This subroutine runs a 'SELECT ... LIMIT 1' style query on the db 445sub db_single { 446 # Get the dbi handle 447 my $self = shift; 448 449 # Get the input structure 450 my $data = shift; 451 452 # Variables we use 453 my $sth = undef; 454 my $result = undef; 455 456 # Check if this is a non-select statement 457# if ( $data->{sql} !~ /^SELECT/i ) { 458# $self->{output} = $self->make_error( $data->{id}, "SINGLE is for SELECT queries only! ( $data->{sql} )" ); 459# return; 460# } 461 462 SWITCH: { 463 if ($data->{begin_work}) { 464 $self->begin_work($data) or last SWITCH; 465 } 466 467 # Catch any errors 468 try { 469 # Make a new statement handler and prepare the query 470 if ($data->{no_cache}) { 471 $sth = $self->{dbh}->prepare( $data->{sql} ); 472 } else { 473 # We use the prepare_cached method in hopes of hitting a cached one... 474 $sth = $self->{dbh}->prepare_cached( $data->{sql} ); 475 } 476 477 # Check for undef'ness 478 if (!defined($sth)) { 479 die 'Did not get a statement handler'; 480 } else { 481 # Execute the query 482 try { 483 $sth->execute( @{ $data->{placeholders} } ); 484 } catch { 485 die ( defined($sth->errstr) ? $sth->errstr : $@ ); 486 }; 487 die $self->{dbh}->errstr if ( $self->{dbh}->errstr ); 488 } 489 490 # Actually do the query! 491 try { 492 # There are warnings when joining a NULL field, which is undef 493 no warnings; 494 if (exists($data->{separator})) { 495 $result = join($data->{separator},$sth->fetchrow_array()); 496 } else { 497 $result = $sth->fetchrow_array(); 498 } 499 } catch { 500 die $sth->errstr; 501 }; 502 503 die $self->{dbh}->errstr if ( $self->{dbh}->errstr ); 504 } catch { 505 $self->{output} = $self->make_error( $data->{id}, shift ); 506 }; 507 } 508 509 # Check if we got any errors 510 if (!defined($self->{output})) { 511 # Make output include the results 512 $self->{output} = { result => $result, id => $data->{id} }; 513 } 514 515 # Finally, we clean up this statement handle 516 if (defined($sth)) { 517 $sth->finish(); 518 } 519 520 return; 521} 522 523# This subroutine does an insert into the db 524sub db_insert { 525 # Get the dbi handle 526 my $self = shift; 527 528 # Get the input structure 529 my $data = shift; 530 531 my $dsn = $self->{dsn} || ''; 532 533 # Variables we use 534 my $sth = undef; 535 my $rows = undef; 536 537 my @queries; 538 my @placeholders; 539 540 # XXX depricate hash for insert 541 if (defined($data->{hash}) && !defined($data->{insert})) { 542 $data->{insert} = delete $data->{hash}; 543 } 544 545 if (defined($data->{insert}) && ref($data->{insert}) eq 'HASH') { 546 $data->{insert} = [$data->{insert}]; 547 } 548 549 # Check if this is a non-insert statement 550 if (defined($data->{insert}) && ref($data->{insert}) eq 'ARRAY') { 551 delete $data->{placeholders}; 552 delete $data->{sql}; 553 foreach my $hash (@{$data->{insert}}) { 554 # sort so we always get a consistant list of fields in the errors and placeholders 555 my @fields = sort keys %{$hash}; 556 # adjust the placeholders, they should know that placeholders passed in are irrelevant 557 # XXX subtypes when a hash value is a HASH or ARRAY? 558 push(@placeholders,[ map { $hash->{$_} } @fields ]); 559 push(@queries,"INSERT INTO $data->{table} (" 560 .join(',',@fields).") VALUES (".join(',',(map { '?' } @fields)).")"); 561 } 562 } elsif (!defined($data->{sql}) || $data->{sql} !~ /^INSERT/i ) { 563 $self->{output} = $self->make_error( $data->{id}, "INSERT is for INSERTS only! ( $data->{sql} )" ); 564 return; 565 } else { 566 push(@queries,$data->{sql}); 567 push(@placeholders,$data->{placeholders}); 568 } 569 570 for my $i ( 0 .. $#queries ) { 571 $data->{sql} = $queries[$i]; 572 $data->{placeholders} = $placeholders[$i]; 573 my $do_last = 0; 574 575 if ($data->{begin_work} && $i == 0) { 576 $self->begin_work($data) or last; 577 } 578 579 # Catch any errors 580 try { 581 # Make a new statement handler and prepare the query 582 if ($data->{no_cache}) { 583 $sth = $self->{dbh}->prepare( $data->{sql} ); 584 } else { 585 # We use the prepare_cached method in hopes of hitting a cached one... 586 $sth = $self->{dbh}->prepare_cached( $data->{sql} ); 587 } 588 589 # Check for undef'ness 590 if (!defined($sth)) { 591 die 'Did not get a statement handler'; 592 } else { 593 # Execute the query 594 try { 595 $rows += $sth->execute( @{ $data->{placeholders} } ); 596 } catch { 597 if (defined($sth->errstr)) { 598 die $sth->errstr; 599 } else { 600 die "error when trying to execute bind of placeholders in insert: $_[0]"; 601 } 602 }; 603 die $self->{dbh}->errstr if ( $self->{dbh}->errstr ); 604 } 605 } catch { 606 my $e = shift; 607 $self->{output} = $self->make_error( $data->{id}, "failed at query #$i : $e" ); 608 $do_last = 1; # can't use last here 609 }; 610 last if ($do_last); 611 } 612 613 if ($data->{commit} && defined($rows) && !defined($self->{output})) { 614 $self->commit($data); 615 } 616 617 # If rows is not undef, that means we were successful 618 if (defined($rows) && !defined($self->{output})) { 619 # Make the data structure 620 $self->{output} = { rows => $rows, result => $rows, id => $data->{id} }; 621 622 unless ($data->{last_insert_id}) { 623 if (defined($sth)) { 624 $sth->finish(); 625 } 626 return; 627 } 628 # get the last insert id 629 try { 630 my $qry = ''; 631 if (ref($data->{last_insert_id}) eq 'HASH') { 632 my $l = $data->{last_insert_id}; 633 # checks for different database types 634 if ($dsn =~ m/dbi:pg/i) { 635 $qry = "SELECT $l->{field} FROM $l->{table} WHERE oid='".$sth->{'pg_oid_status'}."'"; 636 } elsif ($dsn =~ m/dbi:mysql/i) { 637 if (defined($self->{dbh}->{'mysql_insertid'})) { 638 $self->{output}->{insert_id} = $self->{dbh}->{'mysql_insertid'}; 639 } else { 640 $qry = 'SELECT LAST_INSERT_ID()'; 641 } 642 } elsif ($dsn =~ m/dbi:oracle/i) { 643 $qry = "SELECT $l->{field} FROM $l->{table}"; 644 } elsif ($dsn =~ /dbi:sqlite/i) { 645 $self->{output}->{insert_id} = $self->{dbh}->func('last_insert_rowid'); 646 } else { 647 die "EasyDBI doesn't know how to handle a last_insert_id with your dbi, contact the author."; 648 } 649 } else { 650 # they are supplying thier own query 651 $qry = $data->{last_insert_id}; 652 } 653 654 if (defined($sth)) { 655 $sth->finish(); 656 } 657 658 if ($qry) { 659 try { 660 $self->{output}->{insert_id} = $self->{dbh}->selectrow_array($qry); 661 } catch { 662 die $sth->error; 663 }; 664 665 die $self->{dbh}->errstr if ( $self->{dbh}->errstr ); 666 } 667 } catch { 668 # special case, insert was ok, but last_insert_id errored 669 $self->{output}->{error} = shift; 670 }; 671 } elsif (!defined($rows) && !defined($self->{output})) { 672 # Internal error... 673 $self->{output} = $self->make_error( $data->{id}, 'Internal Error in db_do of EasyDBI Subprocess' ); 674 #die 'Internal Error in db_do'; 675 } 676 677 # Finally, we clean up this statement handle 678 if (defined($sth)) { 679 $sth->finish(); 680 } 681 682 return; 683} 684 685# This subroutine runs a 'DO' style query on the db 686sub db_do { 687 # Get the dbi handle 688 my $self = shift; 689 690 # Get the input structure 691 my $data = shift; 692 693 # Variables we use 694 my $sth = undef; 695 my $rows = undef; 696 697 # Check if this is a non-select statement 698# if ( $data->{sql} =~ /^SELECT/i ) { 699# $self->{output} = $self->make_error( $data->{id}, "DO is for non-SELECT queries only! ( $data->{sql} )" ); 700# return; 701# } 702 703 SWITCH: { 704 705 if ($data->{begin_work}) { 706 $self->begin_work($data) or last SWITCH; 707 } 708 709 # Catch any errors 710 try { 711 # Make a new statement handler and prepare the query 712 if ($data->{no_cache}) { 713 $sth = $self->{dbh}->prepare( $data->{sql} ); 714 } else { 715 # We use the prepare_cached method in hopes of hitting a cached one... 716 $sth = $self->{dbh}->prepare_cached( $data->{sql} ); 717 } 718 719 # Check for undef'ness 720 if (!defined($sth)) { 721 die 'Did not get a statement handler'; 722 } else { 723 # Execute the query 724 try { 725 $rows += $sth->execute( @{ $data->{placeholders} } ); 726 } catch { 727 die ( defined($sth->errstr) ? $sth->errstr : $@ ); 728 }; 729 die $self->{dbh}->errstr if ( $self->{dbh}->errstr ); 730 } 731 } catch { 732 $self->{output} = $self->make_error( $data->{id}, shift ); 733 }; 734 735 } 736 737 if ($data->{commit} && defined($rows) && !defined($self->{output})) { 738 $self->commit($data); 739 } 740 741 # If rows is not undef, that means we were successful 742 if (defined($rows) && !defined($self->{output})) { 743 # Make the data structure 744 $self->{output} = { rows => $rows, result => $rows, id => $data->{id} }; 745 } elsif (!defined($rows) && !defined($self->{output})) { 746 # Internal error... 747 $self->{output} = $self->make_error( $data->{id}, 'Internal Error in db_do of EasyDBI Subprocess' ); 748 #die 'Internal Error in db_do'; 749 } 750 751 # Finally, we clean up this statement handle 752 if (defined($sth)) { 753 $sth->finish(); 754 } 755 756 return; 757} 758 759sub db_arrayhash { 760 # Get the dbi handle 761 my $self = shift; 762 763 # Get the input structure 764 my $data = shift; 765 766 # Variables we use 767 my $sth = undef; 768 my $result = []; 769 my $rows = 0; 770 771 # Check if this is a non-select statement 772# if ( $data->{sql} !~ /^SELECT/i ) { 773# $self->{output} = $self->make_error( $data->{id}, "ARRAYHASH is for SELECT queries only! ( $data->{sql} )" ); 774# return; 775# } 776 777 SWITCH: { 778 779 if ($data->{begin_work}) { 780 $self->begin_work($data) or last SWITCH; 781 } 782 783 # Catch any errors 784 try { 785 # Make a new statement handler and prepare the query 786 if ($data->{no_cache}) { 787 $sth = $self->{dbh}->prepare( $data->{sql} ); 788 } else { 789 # We use the prepare_cached method in hopes of hitting a cached one... 790 $sth = $self->{dbh}->prepare_cached( $data->{sql} ); 791 } 792 793 # Check for undef'ness 794 if (!defined($sth)) { 795 die 'Did not get a statement handler'; 796 } else { 797 # Execute the query 798 try { 799 $sth->execute( @{ $data->{placeholders} } ); 800 } catch { 801 die ( defined($sth->errstr) ? $sth->errstr : $@ ); 802 }; 803 die $self->{dbh}->errstr if ( $self->{dbh}->errstr ); 804 } 805 806 # my $newdata; 807 # 808 # # Bind the columns 809 # try { 810 # $sth->bind_columns( \( @$newdata{ @{ $sth->{'NAME_lc'} } } ) ); 811 # } catch { 812 # die $sth->errstr; 813 # }; 814 815 # Actually do the query! 816 try { 817 while ( my $hash = $sth->fetchrow_hashref() ) { 818 if (exists($data->{chunked}) && defined($self->{output})) { 819 # chunk results ready to send 820 $self->output(); 821 $result = []; 822 $rows = 0; 823 } 824 $rows++; 825 # Copy the data, and push it into the array 826 push( @{ $result }, { %{ $hash } } ); 827 if (exists($data->{chunked}) && $data->{chunked} == $rows) { 828 # Make output include the results 829 $self->{output} = { rows => $rows, id => $data->{id}, result => $result, chunked => $data->{chunked} }; 830 } 831 } 832 # in the case that our rows == chunk 833 $self->{output} = undef; 834 835 } catch { 836 die $sth->errstr; 837 }; 838 839 # XXX is dbh->err the same as sth->err? 840 die $self->{dbh}->errstr if ( $self->{dbh}->errstr ); 841 842 # Check for any errors that might have terminated the loop early 843 if ( $sth->err() ) { 844 # Premature termination! 845 die $sth->errstr; 846 } 847 } catch { 848 $self->{output} = $self->make_error( $data->{id}, shift ); 849 }; 850 851 } 852 853 # Check if we got any errors 854 if (!defined($self->{output})) { 855 # Make output include the results 856 $self->{output} = { rows => $rows, id => $data->{id}, result => $result }; 857 if (exists($data->{chunked})) { 858 $self->{output}->{last_chunk} = 1; 859 $self->{output}->{chunked} = $data->{chunked}; 860 } 861 } 862 863 # Finally, we clean up this statement handle 864 if (defined($sth)) { 865 $sth->finish(); 866 } 867 868 return; 869} 870 871sub db_hashhash { 872 # Get the dbi handle 873 my $self = shift; 874 875 # Get the input structure 876 my $data = shift; 877 878 # Variables we use 879 my $sth = undef; 880 my $result = {}; 881 my $rows = 0; 882 883 # Check if this is a non-select statement 884# if ( $data->{sql} !~ /^SELECT/i ) { 885# $self->{output} = $self->make_error( $data->{id}, "HASHHASH is for SELECT queries only! ( $data->{sql} )" ); 886# return; 887# } 888 889 my (@cols, %col); 890 891 SWITCH: { 892 893 if ($data->{begin_work}) { 894 $self->begin_work($data) or last SWITCH; 895 } 896 897 # Catch any errors 898 try { 899 # Make a new statement handler and prepare the query 900 if ($data->{no_cache}) { 901 $sth = $self->{dbh}->prepare( $data->{sql} ); 902 } else { 903 # We use the prepare_cached method in hopes of hitting a cached one... 904 $sth = $self->{dbh}->prepare_cached( $data->{sql} ); 905 } 906 907 # Check for undef'ness 908 if (!defined($sth)) { 909 die 'Did not get a statement handler'; 910 } else { 911 # Execute the query 912 try { 913 $sth->execute( @{ $data->{placeholders} } ); 914 } catch { 915 die ( defined($sth->errstr) ? $sth->errstr : $@ ); 916 }; 917 die $self->{dbh}->errstr if ( $self->{dbh}->errstr ); 918 } 919 920 # The result hash 921 my $newdata = {}; 922 923 # Check the primary key 924 my $foundprimary = 0; 925 926 # default to the first one 927 unless (defined($data->{primary_key})) { 928 $data->{primary_key} = 1; 929 } 930 931 if ($data->{primary_key} =~ m/^\d+$/) { 932 # primary_key can be a 1 based index 933 if ($data->{primary_key} > $sth->{NUM_OF_FIELDS}) { 934 # die "primary_key ($data->{primary_key}) is out of bounds (".$sth->{NUM_OF_FIELDS}.")"; 935 die "primary_key ($data->{primary_key}) is out of bounds"; 936 } 937 938 $data->{primary_key} = $sth->{NAME}->[($data->{primary_key}-1)]; 939 } 940 941 # Find the column names 942 for my $i ( 0 .. $sth->{NUM_OF_FIELDS}-1 ) { 943 $col{$sth->{NAME}->[$i]} = $i; 944 push(@cols, $sth->{NAME}->[$i]); 945 $foundprimary = 1 if ($sth->{NAME}->[$i] eq $data->{primary_key}); 946 } 947 948 unless ($foundprimary == 1) { 949 die "primary key ($data->{primary_key}) not found"; 950 } 951 952 # Actually do the query! 953 try { 954 while ( my @row = $sth->fetchrow_array() ) { 955 if (exists($data->{chunked}) && defined($self->{output})) { 956 # chunk results ready to send 957 $self->output(); 958 $result = {}; 959 $rows = 0; 960 } 961 $rows++; 962 foreach (@cols) { 963 $result->{$row[$col{$data->{primary_key}}]}{$_} = $row[$col{$_}]; 964 } 965 if (exists($data->{chunked}) && $data->{chunked} == $rows) { 966 # Make output include the results 967 $self->{output} = { 968 rows => $rows, 969 result => $result, 970 id => $data->{id}, 971 cols => [ @cols ], 972 chunked => $data->{chunked}, 973 primary_key => $data->{primary_key} 974 }; 975 } 976 } 977 # in the case that our rows == chunk 978 $self->{output} = undef; 979 980 } catch { 981 die $sth->errstr; 982 }; 983 984 die $self->{dbh}->errstr if ( $self->{dbh}->errstr ); 985 986 # Check for any errors that might have terminated the loop early 987 if ( $sth->err() ) { 988 # Premature termination! 989 die $sth->errstr; 990 } 991 } catch { 992 $self->{output} = $self->make_error( $data->{id}, shift ); 993 }; 994 995 } 996 997 # Check if we got any errors 998 if (!defined($self->{output})) { 999 # Make output include the results 1000 $self->{output} = { rows => $rows, id => $data->{id}, result => $result, cols => [ @cols ], primary_key => $data->{primary_key} }; 1001 if (exists($data->{chunked})) { 1002 $self->{output}->{last_chunk} = 1; 1003 $self->{output}->{chunked} = $data->{chunked}; 1004 } 1005 } 1006 1007 # Finally, we clean up this statement handle 1008 if (defined($sth)) { 1009 $sth->finish(); 1010 } 1011 1012 return; 1013} 1014 1015sub db_hasharray { 1016 # Get the dbi handle 1017 my $self = shift; 1018 1019 # Get the input structure 1020 my $data = shift; 1021 1022 # Variables we use 1023 my $sth = undef; 1024 my $result = {}; 1025 my $rows = 0; 1026 1027 # Check if this is a non-select statement 1028# if ( $data->{sql} !~ /^SELECT/i ) { 1029# $self->{output} = $self->make_error( $data->{id}, "HASHARRAY is for SELECT queries only! ( $data->{sql} )" ); 1030# return; 1031# } 1032 1033 my (@cols, %col); 1034 1035 SWITCH: { 1036 1037 if ($data->{begin_work}) { 1038 $self->begin_work($data) or last SWITCH; 1039 } 1040 1041 # Catch any errors 1042 try { 1043 # Make a new statement handler and prepare the query 1044 if ($data->{no_cache}) { 1045 $sth = $self->{dbh}->prepare( $data->{sql} ); 1046 } else { 1047 # We use the prepare_cached method in hopes of hitting a cached one... 1048 $sth = $self->{dbh}->prepare_cached( $data->{sql} ); 1049 } 1050 1051 # Check for undef'ness 1052 if (!defined($sth)) { 1053 die 'Did not get a statement handler'; 1054 } else { 1055 # Execute the query 1056 try { 1057 $sth->execute( @{ $data->{placeholders} } ); 1058 } catch { 1059 die ( defined($sth->errstr) ? $sth->errstr : $@ ); 1060 }; 1061 die $self->{dbh}->errstr if ( $self->{dbh}->errstr ); 1062 } 1063 1064 # The result hash 1065 my $newdata = {}; 1066 1067 # Check the primary key 1068 my $foundprimary = 0; 1069 1070 if ($data->{primary_key} =~ m/^\d+$/) { 1071 # primary_key can be a 1 based index 1072 if ($data->{primary_key} > $sth->{NUM_OF_FIELDS}) { 1073# die "primary_key ($data->{primary_key}) is out of bounds (".$sth->{NUM_OF_FIELDS}.")"; 1074 die "primary_key ($data->{primary_key}) is out of bounds"; 1075 } 1076 1077 $data->{primary_key} = $sth->{NAME}->[($data->{primary_key}-1)]; 1078 } 1079 1080 # Find the column names 1081 for my $i ( 0 .. $sth->{NUM_OF_FIELDS}-1 ) { 1082 $col{$sth->{NAME}->[$i]} = $i; 1083 push(@cols, $sth->{NAME}->[$i]); 1084 $foundprimary = 1 if ($sth->{NAME}->[$i] eq $data->{primary_key}); 1085 } 1086 1087 unless ($foundprimary == 1) { 1088 die "primary key ($data->{primary_key}) not found"; 1089 } 1090 1091 # Actually do the query! 1092 try { 1093 while ( my @row = $sth->fetchrow_array() ) { 1094 if (exists($data->{chunked}) && defined($self->{output})) { 1095 # chunk results ready to send 1096 $self->output(); 1097 $result = {}; 1098 $rows = 0; 1099 } 1100 $rows++; 1101 push(@{ $result->{$row[$col{$data->{primary_key}}]} }, @row); 1102 if (exists($data->{chunked}) && $data->{chunked} == $rows) { 1103 # Make output include the results 1104 $self->{output} = { rows => $rows, result => $result, id => $data->{id}, cols => [ @cols ], chunked => $data->{chunked}, primary_key => $data->{primary_key} }; 1105 } 1106 } 1107 # in the case that our rows == chunk 1108 $self->{output} = undef; 1109 1110 } catch { 1111 die $sth->errstr; 1112 }; 1113 1114 die $self->{dbh}->errstr if ( $self->{dbh}->errstr ); 1115 1116 # Check for any errors that might have terminated the loop early 1117 if ( $sth->err() ) { 1118 # Premature termination! 1119 die $sth->errstr; 1120 } 1121 } catch { 1122 $self->{output} = $self->make_error( $data->{id}, shift ); 1123 }; 1124 1125 } 1126 1127 # Check if we got any errors 1128 if (!defined($self->{output})) { 1129 # Make output include the results 1130 $self->{output} = { rows => $rows, result => $result, id => $data->{id}, cols => [ @cols ], primary_key => $data->{primary_key} }; 1131 if (exists($data->{chunked})) { 1132 $self->{output}->{last_chunk} = 1; 1133 $self->{output}->{chunked} = $data->{chunked}; 1134 } 1135 } 1136 1137 # Finally, we clean up this statement handle 1138 if (defined($sth)) { 1139 $sth->finish(); 1140 } 1141 1142 return; 1143} 1144 1145sub db_array { 1146 # Get the dbi handle 1147 my $self = shift; 1148 1149 # Get the input structure 1150 my $data = shift; 1151 1152 # Variables we use 1153 my $sth = undef; 1154 my $result = []; 1155 my $rows = 0; 1156 1157 # Check if this is a non-select statement 1158# if ( $data->{sql} !~ /^SELECT/i ) { 1159# $self->{output} = $self->make_error( $data->{id}, "ARRAY is for SELECT queries only! ( $data->{sql} )" ); 1160# return; 1161# } 1162 1163 SWITCH: { 1164 1165 if ($data->{begin_work}) { 1166 $self->begin_work($data) or last SWITCH; 1167 } 1168 1169 # Catch any errors 1170 try { 1171 # Make a new statement handler and prepare the query 1172 if ($data->{no_cache}) { 1173 $sth = $self->{dbh}->prepare( $data->{sql} ); 1174 } else { 1175 # We use the prepare_cached method in hopes of hitting a cached one... 1176 $sth = $self->{dbh}->prepare_cached( $data->{sql} ); 1177 } 1178 1179 # Check for undef'ness 1180 if (!defined($sth)) { 1181 die 'Did not get a statement handler'; 1182 } else { 1183 # Execute the query 1184 try { 1185 $sth->execute( @{ $data->{placeholders} } ); 1186 } catch { 1187 die ( defined($sth->errstr) ? $sth->errstr : $@ ); 1188 }; 1189 die $self->{dbh}->errstr if ( $self->{dbh}->errstr ); 1190 } 1191 1192 # The result hash 1193 my $newdata = {}; 1194 1195 # Actually do the query! 1196 try { 1197 # There are warnings when joining a NULL field, which is undef 1198 no warnings; 1199 1200 while ( my @row = $sth->fetchrow_array() ) { 1201 if (exists($data->{chunked}) && defined($self->{output})) { 1202 # chunk results ready to send 1203 $self->output(); 1204 $result = []; 1205 $rows = 0; 1206 } 1207 $rows++; 1208 if (exists($data->{separator})) { 1209 push(@{$result},join($data->{separator},@row)); 1210 } else { 1211 push(@{$result},join(',',@row)); 1212 } 1213 if (exists($data->{chunked}) && $data->{chunked} == $rows) { 1214 # Make output include the results 1215 $self->{output} = { rows => $rows, result => $result, id => $data->{id}, chunked => $data->{chunked} }; 1216 } 1217 } 1218 # in the case that our rows == chunk 1219 $self->{output} = undef; 1220 1221 } catch { 1222 die $!; 1223 #die $sth->errstr; 1224 }; 1225 1226 die $self->{dbh}->errstr if ( $self->{dbh}->errstr ); 1227 1228 # Check for any errors that might have terminated the loop early 1229 if ( $sth->err() ) { 1230 # Premature termination! 1231 die $sth->errstr; 1232 } 1233 } catch { 1234 $self->{output} = $self->make_error( $data->{id}, shift ); 1235 }; 1236 1237 } 1238 1239 # Check if we got any errors 1240 if (!defined($self->{output})) { 1241 # Make output include the results 1242 $self->{output} = { rows => $rows, result => $result, id => $data->{id} }; 1243 if (exists($data->{chunked})) { 1244 $self->{output}->{last_chunk} = 1; 1245 $self->{output}->{chunked} = $data->{chunked}; 1246 } 1247 } 1248 1249 # Finally, we clean up this statement handle 1250 if (defined($sth)) { 1251 $sth->finish(); 1252 } 1253 1254 return; 1255} 1256 1257sub db_arrayarray { 1258 # Get the dbi handle 1259 my $self = shift; 1260 1261 # Get the input structure 1262 my $data = shift; 1263 1264 # Variables we use 1265 my $sth = undef; 1266 my $result = []; 1267 my $rows = 0; 1268 1269 # Check if this is a non-select statement 1270# if ( $data->{sql} !~ /^SELECT/i ) { 1271# $self->{output} = $self->make_error( $data->{id}, "ARRAYARRAY is for SELECT queries only! ( $data->{sql} )" ); 1272# return; 1273# } 1274 1275 SWITCH: { 1276 1277 if ($data->{begin_work}) { 1278 $self->begin_work($data) or last SWITCH; 1279 } 1280 1281 # Catch any errors 1282 try { 1283 # Make a new statement handler and prepare the query 1284 if ($data->{no_cache}) { 1285 $sth = $self->{dbh}->prepare( $data->{sql} ); 1286 } else { 1287 # We use the prepare_cached method in hopes of hitting a cached one... 1288 $sth = $self->{dbh}->prepare_cached( $data->{sql} ); 1289 } 1290 1291 # Check for undef'ness 1292 if (!defined($sth)) { 1293 die 'Did not get a statement handler'; 1294 } else { 1295 # Execute the query 1296 try { 1297 $sth->execute( @{ $data->{placeholders} } ); 1298 } catch { 1299 die ( defined($sth->errstr) ? $sth->errstr : $@ ); 1300 }; 1301 die $self->{dbh}->errstr if ( $self->{dbh}->errstr ); 1302 } 1303 1304 # The result hash 1305 my $newdata = {}; 1306 1307 # Actually do the query! 1308 try { 1309 while ( my @row = $sth->fetchrow_array() ) { 1310 if (exists($data->{chunked}) && defined($self->{output})) { 1311 # chunk results ready to send 1312 $self->output(); 1313 $result = []; 1314 $rows = 0; 1315 } 1316 $rows++; 1317 # There are warnings when joining a NULL field, which is undef 1318 push(@{$result},\@row); 1319 if (exists($data->{chunked}) && $data->{chunked} == $rows) { 1320 # Make output include the results 1321 $self->{output} = { rows => $rows, result => $result, id => $data->{id}, chunked => $data->{chunked} }; 1322 } 1323 } 1324 # in the case that our rows == chunk 1325 $self->{output} = undef; 1326 1327 } catch { 1328 die $!; 1329 #die $sth->errstr; 1330 }; 1331 1332 die $self->{dbh}->errstr if ( $self->{dbh}->errstr ); 1333 1334 # Check for any errors that might have terminated the loop early 1335 if ( $sth->err() ) { 1336 # Premature termination! 1337 die $sth->errstr; 1338 } 1339 } catch { 1340 $self->{output} = $self->make_error( $data->{id}, shift ); 1341 }; 1342 1343 } 1344 1345 1346 # Check if we got any errors 1347 if (!defined($self->{output})) { 1348 # Make output include the results 1349 $self->{output} = { rows => $rows, result => $result, id => $data->{id} }; 1350 if (exists($data->{chunked})) { 1351 $self->{output}->{last_chunk} = 1; 1352 $self->{output}->{chunked} = $data->{chunked}; 1353 } 1354 } 1355 1356 # Finally, we clean up this statement handle 1357 if (defined($sth)) { 1358 $sth->finish(); 1359 } 1360 1361 return; 1362} 1363 1364sub db_hash { 1365 # Get the dbi handle 1366 my $self = shift; 1367 1368 # Get the input structure 1369 my $data = shift; 1370 1371 # Variables we use 1372 my $sth = undef; 1373 my $result = {}; 1374 my $rows = 0; 1375 1376 # Check if this is a non-select statement 1377# if ( $data->{sql} !~ /^SELECT/i ) { 1378# $self->{output} = $self->make_error( $data->{id}, "HASH is for SELECT queries only! ( $data->{sql} )" ); 1379# return; 1380# } 1381 1382 SWITCH: { 1383 1384 if ($data->{begin_work}) { 1385 $self->begin_work($data) or last SWITCH; 1386 } 1387 1388 # Catch any errors 1389 try { 1390 # Make a new statement handler and prepare the query 1391 if ($data->{no_cache}) { 1392 $sth = $self->{dbh}->prepare( $data->{sql} ); 1393 } else { 1394 # We use the prepare_cached method in hopes of hitting a cached one... 1395 $sth = $self->{dbh}->prepare_cached( $data->{sql} ); 1396 } 1397 1398 # Check for undef'ness 1399 if (!defined($sth)) { 1400 die 'Did not get a statement handler'; 1401 } else { 1402 # Execute the query 1403 try { 1404 $sth->execute( @{ $data->{placeholders} } ); 1405 } catch { 1406 die ( defined($sth->errstr) ? $sth->errstr : $@ ); 1407 }; 1408 die $self->{dbh}->errstr if ( $self->{dbh}->errstr ); 1409 } 1410 1411 # The result hash 1412 my $newdata = {}; 1413 1414 # Actually do the query! 1415 try { 1416 1417 my @row = $sth->fetchrow_array(); 1418 1419 if (@row) { 1420 $rows = @row; 1421 for my $i ( 0 .. $sth->{NUM_OF_FIELDS}-1 ) { 1422 $result->{$sth->{NAME}->[$i]} = $row[$i]; 1423 } 1424 } 1425 1426 } catch { 1427 die $sth->errstr; 1428 }; 1429 1430 die $self->{dbh}->errstr if ( $self->{dbh}->errstr ); 1431 1432 # Check for any errors that might have terminated the loop early 1433 if ( $sth->err() ) { 1434 # Premature termination! 1435 die $sth->errstr; 1436 } 1437 } catch { 1438 $self->{output} = $self->make_error( $data->{id}, shift ); 1439 }; 1440 1441 } 1442 1443 # Check if we got any errors 1444 if (!defined($self->{output})) { 1445 # Make output include the results 1446 $self->{output} = { rows => $rows, result => $result, id => $data->{id} }; 1447 } 1448 1449 # Finally, we clean up this statement handle 1450 if (defined($sth)) { 1451 $sth->finish(); 1452 } 1453 1454 return; 1455} 1456 1457sub db_keyvalhash { 1458 # Get the dbi handle 1459 my $self = shift; 1460 1461 # Get the input structure 1462 my $data = shift; 1463 1464 # Variables we use 1465 my $sth = undef; 1466 my $result = {}; 1467 my $rows = 0; 1468 1469 # Check if this is a non-select statement 1470# if ( $data->{sql} !~ /^SELECT/i ) { 1471# $self->{output} = $self->make_error( $data->{id}, "KEYVALHASH is for SELECT queries only! ( $data->{sql} )" ); 1472# return; 1473# } 1474 1475 SWITCH: { 1476 1477 if ($data->{begin_work}) { 1478 $self->begin_work($data) or last SWITCH; 1479 } 1480 1481 # Catch any errors 1482 try { 1483 # Make a new statement handler and prepare the query 1484 if ($data->{no_cache}) { 1485 $sth = $self->{dbh}->prepare( $data->{sql} ); 1486 } else { 1487 # We use the prepare_cached method in hopes of hitting a cached one... 1488 $sth = $self->{dbh}->prepare_cached( $data->{sql} ); 1489 } 1490 1491 # Check for undef'ness 1492 if (!defined($sth)) { 1493 die 'Did not get a statement handler'; 1494 } else { 1495 # Execute the query 1496 try { 1497 $sth->execute( @{ $data->{placeholders} } ); 1498 } catch { 1499 die ( defined($sth->errstr) ? $sth->errstr : $@ ); 1500 }; 1501 die $self->{dbh}->errstr if ( $self->{dbh}->errstr ); 1502 } 1503 1504 # Actually do the query! 1505 try { 1506 while (my @row = $sth->fetchrow_array()) { 1507 if ($#row < 1) { 1508 die 'You need at least 2 columns selected for a keyvalhash query'; 1509 } 1510 if (exists($data->{chunked}) && defined($self->{output})) { 1511 # chunk results ready to send 1512 $self->output(); 1513 $result = {}; 1514 $rows = 0; 1515 } 1516 $rows++; 1517 $result->{$row[0]} = $row[1]; 1518 if (exists($data->{chunked}) && $data->{chunked} == $rows) { 1519 # Make output include the results 1520 $self->{output} = { rows => $rows, result => $result, id => $data->{id}, chunked => $data->{chunked} }; 1521 } 1522 } 1523 # in the case that our rows == chunk 1524 $self->{output} = undef; 1525 1526 } catch { 1527 die $sth->errstr; 1528 }; 1529 1530 die $self->{dbh}->errstr if ( $self->{dbh}->errstr ); 1531 1532 # Check for any errors that might have terminated the loop early 1533 if ( $sth->err() ) { 1534 # Premature termination! 1535 die $sth->errstr; 1536 } 1537 } catch { 1538 $self->{output} = $self->make_error( $data->{id}, shift); 1539 }; 1540 1541 } 1542 1543 # Check if we got any errors 1544 if (!defined($self->{output})) { 1545 # Make output include the results 1546 $self->{output} = { rows => $rows, result => $result, id => $data->{id} }; 1547 if (exists($data->{chunked})) { 1548 $self->{output}->{last_chunk} = 1; 1549 $self->{output}->{chunked} = $data->{chunked}; 1550 } 1551 } 1552 1553 # Finally, we clean up this statement handle 1554 if (defined($sth)) { 1555 $sth->finish(); 1556 } 1557 1558 return; 1559} 1560 1561# Prints any output to STDOUT 1562sub output { 1563 my $self = shift; 1564 1565 # Get the data 1566 my $data = shift || undef; 1567 1568 unless (defined($data)) { 1569 $data = $self->{output}; 1570 $self->{output} = undef; 1571 # TODO use this at some point 1572 $self->{error} = undef; 1573 } 1574 1575 # Freeze it! 1576 my $outdata = $self->{filter}->put( [ $data ] ); 1577 1578 # Print it! 1579 print STDOUT @$outdata; 1580 1581 return; 1582} 1583 15841; 1585 1586__END__ 1587 1588=head1 NAME 1589 1590POE::Component::EasyDBI::SubProcess - Backend of POE::Component::EasyDBI 1591 1592=head1 ABSTRACT 1593 1594This module is responsible for implementing the guts of POE::Component::EasyDBI. 1595The fork and the connection to the DBI. 1596 1597=head2 EXPORT 1598 1599Nothing. 1600 1601=head1 SEE ALSO 1602 1603L<POE::Component::EasyDBI> 1604 1605L<DBI> 1606 1607L<POE> 1608L<POE::Wheel::Run> 1609L<POE::Filter::Reference> 1610 1611L<POE::Component::DBIAgent> 1612L<POE::Component::LaDBI> 1613L<POE::Component::SimpleDBI> 1614 1615=head1 AUTHOR 1616 1617David Davis E<lt>xantus@cpan.orgE<gt> 1618 1619=head1 CREDITS 1620 1621Apocalypse E<lt>apocal@cpan.orgE<gt> 1622 1623=head1 COPYRIGHT AND LICENSE 1624 1625Copyright 2003-2004 by David Davis and Teknikill Software 1626 1627This library is free software; you can redistribute it and/or modify 1628it under the same terms as Perl itself. 1629 1630=cut 1631