home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / xampp / xampp-perl-addon-1.4.9-installer.exe / Query.pm < prev    next >
Encoding:
Perl POD Document  |  2003-05-03  |  4.3 KB  |  183 lines

  1. package Class::DBI::Query::Base;
  2.  
  3. use strict;
  4.  
  5. use base 'Class::Accessor';
  6. use Storable 'dclone';
  7.  
  8. sub new {
  9.     my ($class, $fields) = @_;
  10.     my $self = $class->SUPER::new();
  11.     foreach my $key (keys %{ $fields || {} }) {
  12.         $self->set($key => $fields->{$key});
  13.     }
  14.     $self;
  15. }
  16.  
  17. sub get {
  18.     my ($self, $key) = @_;
  19.     my @vals = @{ $self->{$key} || [] };
  20.     return wantarray ? @vals : $vals[0];
  21. }
  22.  
  23. sub set {
  24.     my ($self, $key, @args) = @_;
  25.     @args = map { ref $_ eq "ARRAY" ? @$_ : $_ } @args;
  26.     $self->{$key} = [@args];
  27. }
  28.  
  29. sub clone { dclone shift }
  30.  
  31. package Class::DBI::Query;
  32.  
  33. use base 'Class::DBI::Query::Base';
  34.  
  35. __PACKAGE__->mk_accessors(
  36.     qw/
  37.         owner essential sqlname where_clause restrictions order_by kings
  38.         /
  39. );
  40.  
  41. =head1 NAME
  42.  
  43. Class::DBI::Query - Manage SQL for Class::DBI
  44.  
  45. =head1 SYNOPSIS
  46.  
  47.     my $sth = Class::DBI::Query
  48.         ->new({ 
  49.             owner => $class, 
  50.             sqlname => $type, 
  51.             essential => \@columns, 
  52.             where_columns => \@where_cols,
  53.         })
  54.         ->run($val);
  55.  
  56.  
  57. =head1 DESCRIPTION
  58.  
  59. This abstracts away many of the details of the Class::DBI underlying SQL
  60. mechanism. For the most part you probably don't want to be interfacing
  61. directly with this.
  62.  
  63. The underlying mechanisms are not yet stable, and are subject to change
  64. at any time.
  65.  
  66. =cut
  67.  
  68. =head1 OPTIONS
  69.  
  70. A Query can have many options set before executing. Most can either be
  71. passed as an option to new(), or set later if you are building the query
  72. up dynamically:
  73.  
  74. =head2 owner
  75.  
  76. The Class::DBI subclass that 'owns' this query. In the vast majority
  77. of cases a query will return objects - the owner is the class of
  78. which instances will be returned. 
  79.  
  80. =head2 sqlname
  81.  
  82. This should be the name of a query set up using set_sql.
  83.  
  84. =head2 where_clause
  85.  
  86. This is the raw SQL that will substituted into the 'WHERE %s' in your
  87. query. If you have multiple %s's in your query then you should supply
  88. a listref of where_clauses. This SQL can include placeholders, which will be 
  89. used when you call run().
  90.  
  91. =head2 essential
  92.  
  93. When retrieving rows from the database that match the WHERE clause of
  94. the query, these are the columns that we fetch back and pre-load the
  95. resulting objects with. By default this is the Essential column group
  96. of the owner class.
  97.  
  98. =head1 METHODS
  99.  
  100. =head2 where()
  101.  
  102.     $query->where($match, @columns);
  103.  
  104. This will extend your 'WHERE' clause by adding a 'AND $column = ?' (or
  105. whatever $match is, isntead of "=") for each column passed. If you have
  106. multiple WHERE clauses this will extend the last one.
  107.  
  108. =cut
  109.  
  110. sub new {
  111.     my ($class, $self) = @_;
  112.     $self->{owner}     ||= caller;
  113.     $self->{kings}     ||= $self->{owner};
  114.     $self->{essential} ||= [ $self->{owner}->_essential ];
  115.     $self->{sqlname}   ||= 'SearchSQL';
  116.     return $class->SUPER::new($self);
  117. }
  118.  
  119. sub _essential_string {
  120.     my $self  = shift;
  121.     my $table = $self->owner->table_alias;
  122.     join ", ", map "$table.$_", $self->essential;
  123. }
  124.  
  125. sub where {
  126.     my ($self, $type, @cols) = @_;
  127.     my @where = $self->where_clause;
  128.     my $last = pop @where || "";
  129.     $last .= join " AND ", $self->restrictions;
  130.     $last .= " ORDER BY " . $self->order_by if $self->order_by;
  131.     push @where, $last;
  132.     return @where;
  133. }
  134.  
  135. sub add_restriction {
  136.     my ($self, $sql) = @_;
  137.     $self->restrictions($self->restrictions, $sql);
  138. }
  139.  
  140. sub tables {
  141.     my $self = shift;
  142.     join ", ", map { join " ", $_->table, $_->table_alias } $self->kings;
  143. }
  144.  
  145. # my $sth = $query->run(@vals);
  146. # Runs the SQL set up in $sqlname, e.g.
  147. #
  148. # SELECT %s (Essential)
  149. # FROM   %s (Table)
  150. # WHERE  %s = ? (SelectCol = @vals)
  151. #
  152. # substituting the relevant values via sprintf, and then executing with $select_val.
  153.  
  154. sub run {
  155.     my $self = shift;
  156.     my $owner = $self->owner or Class::DBI->_croak("Query has no owner");
  157.     $owner = ref $owner || $owner;
  158.     $owner->can('db_Main') or $owner->_croak("No database connection defined");
  159.     my $sql_name = $self->sqlname or $owner->_croak("Query has no SQL");
  160.  
  161.     my @sel_vals = @_
  162.         ? ref $_[0] eq "ARRAY" ? @{ $_[0] } : (@_)
  163.         : ();
  164.     my $sql_method = "sql_$sql_name";
  165.  
  166.     my $sth;
  167.     eval {
  168.         $sth =
  169.             $owner->$sql_method($self->_essential_string, $self->tables,
  170.             $self->where);
  171.         $sth->execute(@sel_vals);
  172.     };
  173.     if ($@) {
  174.         $owner->_croak(
  175.             "Can't select for $owner using '$sth->{Statement}' ($sql_name): $@",
  176.             err => $@);
  177.         return;
  178.     }
  179.     return $sth;
  180. }
  181.  
  182. 1;
  183.