Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 611491d9

Von Sven Schöling vor mehr als 8 Jahren hinzugefügt

  • ID 611491d9d96eb989d1455f87685e57bcaa8f7837
  • Vorgänger 7afe92af
  • Nachfolger 8f56a7e6

DBUtils: doku

Unterschiede anzeigen:

SL/DBUtils.pm
397 397

  
398 398
__END__
399 399

  
400
=encoding utf-8
401

  
400 402
=head1 NAME
401 403

  
402 404
SL::DBUTils.pm: All about database connections in kivitendo
......
426 428

  
427 429
=head1 DESCRIPTION
428 430

  
429
DBUtils is the attempt to reduce the amount of overhead it takes to retrieve information from the database in kivitendo. Previously it would take about 15 lines of code just to get one single integer out of the database, including failure procedures and importing the necessary packages. Debugging would take even more.
431
DBUtils provides wrapper functions for low level database retrieval. It saves
432
you the trouble of mucking around with statement handles for small databse
433
queries and does exception handling in the common cases for you.
434

  
435
Query and retrieval function share the parameter scheme:
436

  
437
  query_or_retrieval(C<FORM, DBH, QUERY[, BINDVALUES]>)
438

  
439
=over 4
440

  
441
=item *
442

  
443
C<FORM> is used for error handling only. It can be omitted in theory, but should
444
not. In most cases you will call it with C<$::form>.
445

  
446
=item *
447

  
448
C<DBH> is a handle to the database, as returned by the C<DBI::connect> routine.
449
If you don't have an active connection, you can use
450
C<<$::form->get_standard_dbh>> to get a generic no_auto connection or get a
451
C<Rose::DB::Object> handle from any RDBO class with
452
C<<SL::DB::Part->new->db->dbh>>. The former will be without autocommit, the
453
latter with autocommit.
454

  
455
See C<PITFALLS AND CAVEATS> for common errors.
456

  
457
=item *
458

  
459
C<QUERY> must be exactly one query. You don't need to include the terminal
460
C<;>. There must be no tainted data interpolated into the string. Instead use
461
the DBI placeholder syntax.
462

  
463
=item *
464

  
465
All additional parameters will be used as C<BINDVALUES> for the query. Note
466
that DBI can't bind arrays to a C<id IN (?)>, so you will need to generate a
467
statement with exactly one C<?> for each bind value. DBI can however bind
468
DateTime objects, and you should always pass these for date selections.
469

  
470
=back
471

  
472
=head1 PITFALLS AND CAVEATS
473

  
474
=head2 Locking
430 475

  
431
Using DBUtils most database procedures can be reduced to defining the query, executing it, and retrieving the result. Let DBUtils handle the rest. Whenever there is a database operation not covered in DBUtils, add it here, rather than working around it in the backend code.
476
As mentioned above, there are two sources of database handles in the program:
477
C<<$::form->get_standard_dbh>> and C<<SL::DB::Object->new->db->dbh>>. It's easy
478
to produce deadlocks when using both of them. To reduce the likelyhood of
479
locks, try to obey these rules:
432 480

  
433
DBUtils relies heavily on two parameters which have to be passed to almost every function: $form and $dbh.
434
  - $form is used for error handling only. It can be omitted in theory, but should not.
435
  - $dbh is a handle to the database, as returned by the DBI::connect routine. If you don't have an active connection, you can query $form->get_standard_dbh() to get a generic no_auto connection. Don't forget to commit in this case!
481
=over 4
482

  
483
=item *
484

  
485
In a controller that uses Rose objects, never use C<get_standard_dbh>.
486

  
487
=item *
488

  
489
In backend code, that has no preference, always accept the database handle as a
490
parameter from the controller.
491

  
492
=back
493

  
494
=head2 Exports
495

  
496
C<DBUtils> is one of the last modules in the program to use C<@EXPORT> instead
497
of C<@EXPORT_OK>. This means it will flood your namespace with its functions,
498
causing potential clashes. When writing new code, always either export nothing
499
and call directly:
436 500

  
501
  use SL::DBUtils ();
502
  DBUtils::selectall_hashref_query(...)
437 503

  
438
Every function here should accomplish the follwing things:
439
  - Easy debugging. Every handled query gets dumped via LXDebug, if specified there.
440
  - Safe value binding. Although DBI is far from perfect in terms of binding, the rest of the bindings should happen here.
441
  - Error handling. Should a query fail, an error message will be generated here instead of in the backend code invoking DBUtils.
504
or export only what you need:
442 505

  
443
Note that binding is not perfect here either...
506
  use SL::DBUtils qw(selectall_hashref_query);
507
  selectall_hashref_query(...)
444 508

  
445
=head2 QUOTING FUNCTIONS
509

  
510
=head2 Peformance
511

  
512
Since it is really easy to write something like
513

  
514
  my $all_parts = selectall_hashref_query($::form, $dbh, 'SELECT * FROM parts');
515

  
516
people do so from time to time. When writing code, consider this a ticking
517
timebomb. Someone out there has a database with 1mio parts in it, and this
518
statement just shovelled ate 2GB of memory and timeouted the request.
519

  
520
Parts may be the obvious example, but the same applies to customer, vendors,
521
records, projects or custom variables.
522

  
523

  
524
=head1 QUOTING FUNCTIONS
446 525

  
447 526
=over 4
448 527

  
......
450 529

  
451 530
=item conv_i STR,DEFAULT
452 531

  
453
Converts STR to an integer. If STR is empty, returns DEFAULT. If no DEFAULT is given, returns undef.
532
Converts STR to an integer. If STR is empty, returns DEFAULT. If no DEFAULT is
533
given, returns undef.
454 534

  
455 535
=item conv_date STR
456 536

  
......
458 538

  
459 539
=item conv_dateq STR
460 540

  
461
Database version of conv_date. Quotes STR before returning. Returns 'NULL' if STR is empty.
541
Database version of conv_date. Quotes STR before returning. Returns 'NULL' if
542
STR is empty.
462 543

  
463 544
=item quote_db_date STR
464 545

  
465
Treats STR as a database date, quoting it. If STR equals current_date returns an escaped version which is treated as the current date by Postgres.
466
Returns 'NULL' if STR is empty.
546
Treats STR as a database date, quoting it. If STR equals current_date returns
547
an escaped version which is treated as the current date by Postgres.
548

  
549
Returns C<'NULL'> if STR is empty.
467 550

  
468 551
=item like STR
469 552

  
......
473 556

  
474 557
=back
475 558

  
476
=head2 QUERY FUNCTIONS
559
=head1 QUERY FUNCTIONS
477 560

  
478 561
=over 4
479 562

  
480 563
=item do_query FORM,DBH,QUERY,ARRAY
481 564

  
482
Uses DBI::do to execute QUERY on DBH using ARRAY for binding values. FORM is only needed for error handling, but should always be passed nevertheless. Use this for insertions or updates that don't need to be prepared.
565
Uses DBI::do to execute QUERY on DBH using ARRAY for binding values. FORM is
566
only needed for error handling, but should always be passed nevertheless. Use
567
this for insertions or updates that don't need to be prepared.
483 568

  
484
Returns the result of DBI::do which is -1 in case of an error and the number of affected rows otherwise.
569
Returns the result of DBI::do which is -1 in case of an error and the number of
570
affected rows otherwise.
485 571

  
486 572
=item do_statement FORM,STH,QUERY,ARRAY
487 573

  
488
Uses DBI::execute to execute QUERY on DBH using ARRAY for binding values. As with do_query, FORM is only used for error handling. If you are unsure what to use, refer to the documentation of DBI::do and DBI::execute.
574
Uses DBI::execute to execute QUERY on DBH using ARRAY for binding values. As
575
with do_query, FORM is only used for error handling. If you are unsure what to
576
use, refer to the documentation of DBI::do and DBI::execute.
489 577

  
490
Returns the result of DBI::execute which is -1 in case of an error and the number of affected rows otherwise.
578
Returns the result of DBI::execute which is -1 in case of an error and the
579
number of affected rows otherwise.
491 580

  
492 581
=item prepare_execute_query FORM,DBH,QUERY,ARRAY
493 582

  
494
Prepares and executes QUERY on DBH using DBI::prepare and DBI::execute. ARRAY is passed as binding values to execute.
583
Prepares and executes QUERY on DBH using DBI::prepare and DBI::execute. ARRAY
584
is passed as binding values to execute.
495 585

  
496 586
=back
497 587

  
498
=head2 RETRIEVAL FUNCTIONS
588
=head1 RETRIEVAL FUNCTIONS
499 589

  
500 590
=over 4
501 591

  
......
503 593

  
504 594
=item selectrow_query FORM,DBH,QUERY,ARRAY
505 595

  
506
Prepares and executes a query using DBUtils functions, retireves the first row from the database, and returns it as an arrayref of the first row.
596
Prepares and executes a query using DBUtils functions, retireves the first row
597
from the database, and returns it as an arrayref of the first row.
507 598

  
508 599
=item selectfirst_hashref_query FORM,DBH,QUERY,ARRAY
509 600

  
510
Prepares and executes a query using DBUtils functions, retireves the first row from the database, and returns it as a hashref of the first row.
601
Prepares and executes a query using DBUtils functions, retireves the first row
602
from the database, and returns it as a hashref of the first row.
511 603

  
512 604
=item selectall_hashref_query FORM,DBH,QUERY,ARRAY
513 605

  
514
Prepares and executes a query using DBUtils functions, retireves all data from the database, and returns it in hashref mode. This is slightly confusing, as the data structure will actually be a reference to an array, containing hashrefs for each row.
606
Prepares and executes a query using DBUtils functions, retireves all data from
607
the database, and returns it in hashref mode. This is slightly confusing, as
608
the data structure will actually be a reference to an array, containing
609
hashrefs for each row.
515 610

  
516 611
=item selectall_as_map FORM,DBH,QUERY,KEY_COL,VALUE_COL,ARRAY
517 612

  
518
Prepares and executes a query using DBUtils functions, retireves all data from the database, and creates a hash from the results using KEY_COL as the column for the hash keys and VALUE_COL for its values.
613
Prepares and executes a query using DBUtils functions, retireves all data from
614
the database, and creates a hash from the results using KEY_COL as the column
615
for the hash keys and VALUE_COL for its values.
519 616

  
520 617
=back
521 618

  
522
=head2 UTILITY FUNCTIONS
619
=head1 UTILITY FUNCTIONS
523 620

  
524 621
=over 4
525 622

  
......
547 644
names as they may come from the application. The values are either
548 645
scalars with SQL code or array references of SQL code. Example:
549 646

  
550
'defs' => { 'customername' => 'lower(customer.name)',
551
            'address'      => [ 'lower(customer.city)', 'lower(customer.street)' ], }
647
  defs => {
648
    customername => 'lower(customer.name)',
649
    address      => [ 'lower(customer.city)', 'lower(customer.street)' ],
650
  }
552 651

  
553 652
'default' is the default column name to sort by. It must be a key of
554 653
'defs' and should not be come from user input.
......
569 668

  
570 669
=back
571 670

  
572
=head2 DEBUG FUNCTIONS
671
=head1 DEBUG FUNCTIONS
573 672

  
574 673
=over 4
575 674

  
576 675
=item dump_query LEVEL,MSG,QUERY,ARRAY
577 676

  
578
Dumps a query using LXDebug->message, using LEVEL for the debug-level of LXDebug. If MSG is given, it preceeds the QUERY dump in the logfiles. ARRAY is used to interpolate the '?' placeholders in QUERY, the resulting QUERY can be copy-pasted into a database frontend for debugging. Note that this method is also automatically called by each of the other QUERY FUNCTIONS, so there is in general little need to invoke it manually.
677
Dumps a query using LXDebug->message, using LEVEL for the debug-level of
678
LXDebug. If MSG is given, it preceeds the QUERY dump in the logfiles. ARRAY is
679
used to interpolate the '?' placeholders in QUERY, the resulting QUERY can be
680
copy-pasted into a database frontend for debugging. Note that this method is
681
also automatically called by each of the other QUERY FUNCTIONS, so there is in
682
general little need to invoke it manually.
579 683

  
580 684
=back
581 685

  
......
603 707
  my @values;
604 708

  
605 709
  if ($form->{language_values} ne "") {
606
    $query = qq|SELECT l.id, l.description, tr.translation, tr.longdescription
607
                  FROM language l
608
                  LEFT OUTER JOIN translation tr ON (tr.language_id = l.id) AND (tr.parts_id = ?)|;
710
    $query = qq|
711
      SELECT l.id, l.description, tr.translation, tr.longdescription
712
      FROM language l
713
      LEFT JOIN translation tr ON (tr.language_id = l.id AND tr.parts_id = ?)
714
    |;
609 715
    @values = (conv_i($form->{id}));
610 716
  } else {
611 717
    $query = qq|SELECT id, description FROM language|;
......
617 723

  
618 724
=head1 MODULE AUTHORS
619 725

  
620
Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
621
Sven Schoeling E<lt>s.schoeling@linet-services.deE<gt>
726
  Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
727
  Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
622 728

  
623 729
=head1 DOCUMENTATION AUTHORS
624 730

  
625
Udo Spallek E<lt>udono@gmx.netE<gt>
626
Sven Schoeling E<lt>s.schoeling@linet-services.deE<gt>
731
  Udo Spallek E<lt>udono@gmx.netE<gt>
732
  Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
627 733

  
628 734
=head1 COPYRIGHT AND LICENSE
629 735

  

Auch abrufbar als: Unified diff