File Coverage

blib/lib/Dancer/Plugin/Database/Core/Handle.pm
Criterion Covered Total %
statement 90 156 57.6
branch 41 98 41.8
condition 19 51 37.2
subroutine 9 16 56.2
pod 6 7 85.7
total 165 328 50.3


line stmt bran cond sub pod time code
1             package Dancer::Plugin::Database::Core::Handle;
2              
3 2     2   29129 use strict;
  2         4  
  2         44  
4 2     2   6 use Carp;
  2         2  
  2         111  
5 2     2   1455 use DBI;
  2         12470  
  2         77  
6 2     2   10 use base qw(DBI::db);
  2         2  
  2         3769  
7              
8             our $VERSION = '0.16';
9              
10             =head1 NAME
11              
12             Dancer::Plugin::Database::Core::Handle - subclassed DBI connection handle
13              
14             =head1 DESCRIPTION
15              
16             Subclassed DBI connection handle with added convenience features
17              
18              
19             =head1 SYNOPSIS
20              
21             # in your Dancer app:
22             database->quick_insert($tablename, \%data);
23              
24             # Updating a record where id = 42:
25             database->quick_update($tablename, { id => 42 }, { foo => 'New value' });
26              
27             # Fetching a single row quickly in scalar context
28             my $employee = database->quick_select('employees', { id => $emp_id });
29              
30             # Fetching multiple rows in list context - passing an empty hashref to signify
31             # no where clause (i.e. return all rows - so "select * from $table_name"):
32             my @all_employees = database->quick_select('employees', {});
33              
34             # count number of male employees
35             my $count = database->quick_count('employees', { gender => 'male' });
36              
37             =head1 Added features
38              
39             A C object is a subclassed L L
40             database handle, with the following added convenience methods:
41              
42             =over 4
43              
44             =item quick_insert
45              
46             database->quick_insert('mytable', { foo => 'Bar', baz => 5 });
47              
48             Given a table name and a hashref of data (where keys are column names, and the
49             values are, well, the values), insert a row in the table.
50              
51             If you need any of the values to be interpolated straight into the SQL, for
52             instance if you need to use a function call like C or similar, then you
53             can provide them as a scalarref:
54              
55             database->quick_insert('mytable', { foo => 'Bar', timestamp => \'NOW()' });
56              
57             Of course, if you do that, you must be careful to avoid SQL injection attacks!
58             =cut
59              
60             sub quick_insert {
61 0     0 1 0 my ($self, $table_name, $data) = @_;
62 0         0 return $self->_quick_query('INSERT', $table_name, $data);
63             }
64              
65             =item quick_update
66              
67             database->quick_update('mytable', { id => 42 }, { foo => 'Baz' });
68              
69             Given a table name, a hashref describing a where clause and a hashref of
70             changes, update a row.
71              
72             As per quick_insert, if you need any of the values to be interpolated straight
73             in the SQL, for e.g. to use a function call, provide a scalarref:
74              
75             database->quick_update('mytable', { id => 42 }, { counter => \'counter + 1' });
76              
77             Of course, if you do that, you must be careful to avoid SQL injection attacks!
78              
79             =cut
80              
81             sub quick_update {
82 0     0 1 0 my ($self, $table_name, $where, $data) = @_;
83 0         0 return $self->_quick_query('UPDATE', $table_name, $data, $where);
84             }
85              
86              
87             =item quick_delete
88              
89             database->quick_delete($table, { id => 42 });
90              
91             Given a table name and a hashref to describe the rows which should be deleted
92             (the where clause - see below for further details), delete them.
93              
94             =cut
95              
96             sub quick_delete {
97 0     0 1 0 my ($self, $table_name, $where) = @_;
98 0         0 return $self->_quick_query('DELETE', $table_name, undef, $where);
99             }
100              
101              
102             =item quick_select
103              
104             my $row = database->quick_select($table, { id => 42 });
105             my @rows = database->quick_select($table, { id => 42 });
106              
107             Given a table name and a hashref of where clauses (see below for explanation),
108             and an optional hashref of options, returns either the first matching
109             row as a hashref if called in scalar context, or a list of matching rows
110             as hashrefs if called in list context. The third argument is a hashref of
111             options to allow additional control, as documented below. For backwards
112             compatibility, it can also be an arrayref of column names, which acts in the
113             same way as the C option.
114              
115             The options you can provide are:
116              
117             =over 4
118              
119             =item C
120              
121             An arrayref of column names to return, if you only want certain columns returned
122              
123             =item C
124              
125             Specify how the results should be ordered. This option can take various values:
126              
127             =over 4
128              
129             =item * a straight scalar or arrayref sorts by the given column(s):
130              
131             { order_by => 'foo' } # equivalent to "ORDER BY foo"
132             { order_by => [ qw(foo bar) ] } # equiv to "ORDER BY foo,bar"
133              
134             =item * a hashref of C column name>, e.g.:
135              
136             { order_by => { desc => 'foo' } } # equiv to ORDER BY foo DESC
137             { order_by => [ { desc => 'foo' }, { asc => 'bar' } ] }
138             # above is equiv to ORDER BY foo DESC, bar ASC
139              
140             =back
141              
142             =item C
143              
144             Limit how many records will be returned; equivalent to e.g. C in an SQL
145             query. If called in scalar context, an implicit LIMIT 1 will be added to the
146             query anyway, so you needn't add it yourself.
147              
148             An example of using options to control the results you get back:
149              
150             # Get the name & phone number of the 10 highest-paid men:
151             database->quick_select(
152             'employees',
153             { gender => 'male' },
154             { order_by => 'salary', limit => 10, columns => [qw(name phone)] }
155             );
156              
157             =cut
158              
159             =item C number
160              
161             C says to skip that many rows before beginning to return rows (postgresql).
162              
163              
164             Example:
165              
166             # Get the name & phone number of the 10 highest-paid men starting from 11th:
167             database->quick_select(
168             'employees',
169             { gender => 'male' },
170             { order_by => 'salary', offset => 10, limit => 10, columns => [qw(name phone)] }
171             );
172              
173              
174             =cut
175              
176             sub quick_select {
177 0     0 1 0 my ($self, $table_name, $where, $opts) = @_;
178              
179             # For backwards compatibility, accept an arrayref of column names as the 3rd
180             # arg, instead of an arrayref of options:
181 0 0 0     0 if ($opts && ref $opts eq 'ARRAY') {
182 0         0 $opts = { columns => $opts };
183             }
184              
185             # Make sure to call _quick_query in the same context we were called.
186             # This is a little ugly, rewrite this perhaps.
187 0 0       0 if (wantarray) {
188 0         0 return ($self->_quick_query('SELECT', $table_name, $opts, $where));
189             } else {
190 0         0 return $self->_quick_query('SELECT', $table_name, $opts, $where);
191             }
192             }
193              
194             =back
195              
196             =item quick_lookup
197              
198             my $id = database->quick_lookup($table, { email => $params->{'email'} }, 'userid' );
199              
200             This is a bit of syntactic sugar when you just want to lookup a specific
201             field, such as when you're converting an email address to a userid (say
202             during a login handler.)
203              
204             This call always returns a single scalar value, not a hashref of the
205             entire row (or partial row) like most of the other methods in this library.
206              
207             Returns undef when there's no matching row or no such field found in
208             the results.
209              
210             =cut
211              
212             sub quick_lookup {
213 0     0 1 0 my ($self, $table_name, $where, $data) = @_;
214 0         0 my $opts = { columns => [$data] };
215 0         0 my $row = $self->_quick_query('SELECT', $table_name, $opts, $where);
216              
217 0 0 0     0 return ( $row && exists $row->{$data} ) ? $row->{$data} : undef;
218             }
219              
220             =item quick_count
221              
222             my $count = database->quick_count($table,
223             { email => $params->{'email'} });
224              
225             This is syntactic sugar to return a count of all rows which match your
226             parameters, useful for pagination.
227              
228             This call always returns a single scalar value, not a hashref of the
229             entire row (or partial row) like most of the other methods in this
230             library.
231              
232             =cut
233              
234             sub quick_count {
235 0     0 1 0 my ($self, $table_name, $where) = @_;
236 0         0 my $opts = {}; #Options are irrelevant for a count.
237 0         0 my @row = $self->_quick_query('COUNT', $table_name, $opts, $where);
238              
239 0 0       0 return ( @row ) ? $row[0] : undef ;
240             }
241              
242             # The 3rd arg, $data, has a different meaning depending on the type of query
243             # (no, I don't like that much; I may refactor this soon to use named params).
244             # For INSERT/UPDATE queries, it'll be a hashref of field => value.
245             # For SELECT queries, it'll be a hashref of additional options.
246             # For DELETE queries, it's unused.
247             sub _quick_query {
248 0     0   0 my ($self, $type, $table_name, $data, $where) = @_;
249            
250             # Basic sanity checks first...
251 0 0       0 if ($type !~ m{^ (SELECT|INSERT|UPDATE|DELETE|COUNT) $}x) {
252 0         0 carp "Unrecognised query type $type!";
253 0         0 return;
254             }
255 0 0 0     0 if (!$table_name || ref $table_name) {
256 0         0 carp "Expected table name as a straight scalar";
257 0         0 return;
258             }
259 0 0 0     0 if (($type eq 'INSERT' || $type eq 'UPDATE')
      0        
      0        
260             && (!$data || ref $data ne 'HASH'))
261             {
262 0         0 carp "Expected a hashref of changes";
263 0         0 return;
264             }
265 0 0 0     0 if (($type =~ m{^ (SELECT|UPDATE|DELETE|COUNT) $}x)
266             && (!$where)) {
267 0         0 carp "Expected where conditions";
268 0         0 return;
269             }
270              
271             # OK, get the SQL we're going to need
272             # TODO: can we replace our own generation with e.g. SQL::Abstract? How much
273             # backwards-incompatible change would that incur?
274 0         0 my ($sql, @bind_params) = $self->_generate_sql(
275             $type, $table_name, $data, $where
276             );
277              
278              
279             # Dancer::Plugin::Database will have looked at the log_queries setting and
280             # stashed it away for us to see:
281 0 0       0 if ($self->{private_dancer_plugin_database}{log_queries}) {
282             $self->{private_dancer_plugin_database}{logger}->(debug =>
283             "Executing $type query $sql with params " . join ',',
284             map {
285 0 0       0 defined $_ ?
  0 0       0  
    0          
286             $_ =~ /^[[:ascii:]]+$/ ?
287             length $_ > 50 ? substr($_, 0, 47) . '...' : $_
288             : "[non-ASCII data not logged]" : 'undef'
289             } @bind_params
290             );
291             }
292              
293             # Select queries, in scalar context, return the first matching row; in list
294             # context, they return a list of matching rows.
295 0 0       0 if ($type eq 'SELECT') {
    0          
296 0 0       0 if (wantarray) {
297             return @{
298 0         0 $self->selectall_arrayref(
  0         0  
299             $sql, { Slice => {} }, @bind_params
300             )
301             };
302             } else {
303 0         0 return $self->selectrow_hashref($sql, undef, @bind_params);
304             }
305              
306             } elsif ($type eq 'COUNT') {
307 0         0 return $self->selectrow_array($sql, undef, @bind_params);
308             } else {
309             # INSERT/UPDATE/DELETE queries just return the result of DBI's do()
310 0         0 return $self->do($sql, undef, @bind_params);
311             }
312             }
313              
314             sub _generate_sql {
315 8     8   5652 my ($self, $type, $table_name, $data, $where) = @_;
316              
317 8         9 my $which_cols = '*';
318 8 100 100     33 my $opts = $type eq 'SELECT' && $data ? $data : {};
319 8 100       16 if ($opts->{columns}) {
320             my @cols = (ref $opts->{columns})
321 1         3 ? @{ $opts->{columns} }
322 1 50       4 : $opts->{columns} ;
323 1         3 $which_cols = join(',', map { $self->_quote_identifier($_) } @cols);
  2         17  
324             }
325              
326 8         21 $table_name = $self->_quote_identifier($table_name);
327 8         118 my @bind_params;
328              
329             my $sql = {
330             SELECT => "SELECT $which_cols FROM $table_name",
331             INSERT => "INSERT INTO $table_name ",
332             UPDATE => "UPDATE $table_name SET ",
333             DELETE => "DELETE FROM $table_name ",
334             COUNT => "SELECT COUNT(*) FROM $table_name",
335 8         41 }->{$type};
336 8 100       22 if ($type eq 'INSERT') {
337 1         1 my (@keys, @values);
338 1         4 for my $key (sort keys %$data) {
339 2         3 my $value = $data->{$key};
340 2         3 push @keys, $self->_quote_identifier($key);
341 2 100       27 if (ref $value eq 'SCALAR') {
342             # If it's a scalarref it goes in the SQL as it is; this is a
343             # potential SQL injection risk, but is documented as such - it
344             # allows the user to include arbitrary SQL, at their own risk.
345 1         2 push @values, $$value;
346             } else {
347 1         1 push @values, "?";
348 1         3 push @bind_params, $value;
349             }
350             }
351              
352 1         5 $sql .= sprintf "(%s) VALUES (%s)",
353             join(',', @keys), join(',', @values);
354             }
355              
356 8 100       14 if ($type eq 'UPDATE') {
357 1         2 my @sql;
358 1         5 for (sort keys %$data) {
359             push @sql, $self->_quote_identifier($_) . '=' .
360 2 100       4 (ref $data->{$_} eq 'SCALAR' ? ${$data->{$_}} : "?");
  1         17  
361 2 100       19 push @bind_params, $data->{$_} if (ref $data->{$_} ne 'SCALAR');
362             }
363 1         2 $sql .= join ',', @sql;
364             }
365              
366 8 100 66     38 if ($type eq 'UPDATE' || $type eq 'DELETE' || $type eq 'SELECT' || $type eq 'COUNT')
      100        
      66        
367             {
368 7 100       13 if ($where) {
369 5         7 my ($where_sql, @where_binds) = $self->generate_where_clauses( $where );
370             # Note: it's reasonable to get back no $where_sql in some cases -
371             # for e.g. if $where was an empty hashref, to denote "no
372             # conditions" - so it's not an error to not get any clauses to add.
373 5 50       8 if ($where_sql) {
374 5         7 $sql .= " WHERE $where_sql";
375 5         5 push(@bind_params, @where_binds);
376             }
377             }
378             }
379             # Add an ORDER BY clause, if we want to:
380 8 50 33     23 if (exists $opts->{order_by} and defined $opts->{order_by}) {
381 0         0 $sql .= ' ' . $self->_build_order_by_clause($opts->{order_by});
382             }
383              
384              
385             # Add a LIMIT clause if we want to:
386 8 50 33     34 if (exists $opts->{limit} and defined $opts->{limit}) {
    50 66        
387 0         0 my $limit = $opts->{limit};
388 0         0 $limit =~ s/\s+//g;
389             # Check the limit clause is sane - just a number, or two numbers with a
390             # comma between (if using offset,limit )
391 0 0       0 if ($limit =~ m{ ^ \d+ (?: , \d+)? $ }x) {
392             # Checked for sanity above so safe to interpolate
393 0         0 $sql .= " LIMIT $limit";
394             } else {
395 0         0 die "Invalid LIMIT param $opts->{limit} !";
396             }
397             } elsif ($type eq 'SELECT' && !wantarray) {
398             # We're only returning one row in scalar context, so don't ask for any
399             # more than that
400 0         0 $sql .= " LIMIT 1";
401             }
402            
403 8 50 33     16 if (exists $opts->{offset} and defined $opts->{offset}) {
404 0         0 my $offset = $opts->{offset};
405 0         0 $offset =~ s/\s+//g;
406 0 0       0 if ($offset =~ /^\d+$/) {
407 0         0 $sql .= " OFFSET $offset";
408             } else {
409 0         0 die "Invalid OFFSET param $opts->{offset} !";
410             }
411             }
412 8         24 return ($sql, @bind_params);
413             }
414              
415             sub generate_where_clauses {
416 5     5 0 6 my ($self, $where) = @_;
417 5         6 my $sql = "";
418 5         3 my @bind_params;
419 5 100 66     25 if ($where && !ref $where) {
    50          
    0          
420 1         2 $sql .= $where;
421             } elsif ( ref $where eq 'HASH' ) {
422 4         4 my @stmts;
423 4         23 foreach my $k ( sort keys %$where ) {
424 7         7 my $v = $where->{$k};
425 7 100       10 if ( ref $v eq 'HASH' ) {
426 2         4 my $not = delete $v->{'not'};
427 2         7 while (my($op,$value) = each %$v ) {
428 2         5 my ($cond, $add_bind_param)
429             = $self->_get_where_sql_clause($op, $not, $value);
430 2         5 push @stmts, $self->_quote_identifier($k) . $cond;
431 2 50       37 push @bind_params, $v->{$op} if $add_bind_param;
432             }
433             } else {
434 5         7 my $clause .= $self->_quote_identifier($k);
435 5 50       70 if ( ! defined $v ) {
    50          
    0          
436 0         0 $clause .= ' IS NULL';
437             }
438             elsif ( ! ref $v ) {
439 5         2 $clause .= '=?';
440 5         5 push @bind_params, $v;
441             }
442             elsif ( ref $v eq 'ARRAY' ) {
443 0         0 $clause .= ' IN (' . (join ',', map { '?' } @$v) . ')';
  0         0  
444 0         0 push @bind_params, @$v;
445             }
446 5         9 push @stmts, $clause;
447             }
448             }
449 4 50       13 $sql .= join " AND ", @stmts if keys %$where;
450             } elsif (ref $where) {
451 0         0 carp "Can't handle ref " . ref $where . " for where";
452 0         0 return;
453             }
454 5         9 return ($sql, @bind_params);
455             }
456              
457              
458             sub _get_where_sql_clause {
459 2     2   3 my ($self, $op, $not, $value) = @_;
460              
461 2         4 $op = lc $op;
462              
463             # "IS" needs special-casing, as it will be either "IS NULL" or "IS NOT NULL"
464             # - there's no need to return a bind param for that.
465 2 50       3 if ($op eq 'is') {
466 0 0       0 if (defined $value) {
467 0         0 $self->{private_dancer_plugin_database}{logger}->(warning =>
468             "Using the 'IS' operator only makes sense to test for nullness,"
469             ." but a non-undef value was passed. Did you mean eq/ne?"
470             );
471             }
472 0 0       0 return $not ? 'IS NOT NULL' : 'IS NULL';
473             }
474              
475 2         12 my %st = (
476             'ilike'=> ' ILIKE ?',
477             'like' => ' LIKE ?',
478             'is' => ' IS ?',
479             'ge' => ' >= ?',
480             'gt' => ' > ?',
481             'le' => ' <= ?',
482             'lt' => ' < ?',
483             'eq' => ' = ?',
484             'ne' => ' != ?',
485             );
486              
487             # Return the appropriate SQL, and indicate that the value should be added to
488             # the bind params
489 2 50       7 return (($not ? ' NOT' . $st{$op} : $st{$op}), 1);
490             }
491              
492             # Given either a column name, or a hashref of e.g. { asc => 'colname' },
493             # or an arrayref of either, construct an ORDER BY clause (quoting col names)
494             # e.g.:
495             # 'foo' => ORDER BY foo
496             # { asc => 'foo' } => ORDER BY foo ASC
497             # ['foo', 'bar'] => ORDER BY foo, bar
498             # [ { asc => 'foo' }, { desc => 'bar' } ]
499             # => 'ORDER BY foo ASC, bar DESC
500             sub _build_order_by_clause {
501 4     4   3735 my ($self, $in) = @_;
502              
503             # Input could be a straight scalar, or a hashref, or an arrayref of either
504             # straight scalars or hashrefs. Turn a straight scalar into an arrayref to
505             # avoid repeating ourselves.
506 4 100       13 $in = [ $in ] unless ref $in eq 'ARRAY';
507              
508             # Now, for each of the fields given, add them to the clause
509 4         5 my @sort_fields;
510 4         5 for my $field (@$in) {
511 6 100       47 if (!ref $field) {
    50          
512 3         5 push @sort_fields, $self->_quote_identifier($field);
513             } elsif (ref $field eq 'HASH') {
514 3         9 my ($order, $name) = %$field;
515 3         6 $order = uc $order;
516 3 50 66     11 if ($order ne 'ASC' && $order ne 'DESC') {
517 0         0 die "Invalid sort order $order used in order_by option!";
518             }
519             # $order has been checked to be 'ASC' or 'DESC' above, so safe to
520             # interpolate
521 3         5 push @sort_fields, $self->_quote_identifier($name) . " $order";
522             }
523             }
524              
525 4         98 return "ORDER BY " . join ', ', @sort_fields;
526             }
527              
528             # A wrapper around DBI's quote_identifier which first splits on ".", so that
529             # e.g. database.table gets quoted as `database`.`table`, not `database.table`
530             sub _quote_identifier {
531 29     29   715 my ($self, $identifier) = @_;
532              
533             return join '.', map {
534 29         51 $self->quote_identifier($_)
  30         101  
535             } split /\./, $identifier;
536             }
537              
538             =back
539              
540             All of the convenience methods provided take care to quote table and column
541             names using DBI's C, and use parameterised queries to avoid
542             SQL injection attacks. See L for why this is
543             important, if you're not familiar with it.
544              
545              
546             =head1 WHERE clauses as hashrefs
547              
548             C, C and C take a hashref of WHERE
549             clauses. This is a hashref of field => 'value', each of which will be
550             included in the WHERE clause used, for instance:
551              
552             { id => 42 }
553              
554             Will result in an SQL query which would include:
555              
556             WHERE id = 42
557              
558             When more than one field => value pair is given, they will be ANDed together:
559              
560             { foo => 'Bar', bar => 'Baz' }
561              
562             Will result in:
563              
564             WHERE foo = 'Bar' AND bar = 'Baz'
565              
566             (Actually, parameterised queries will be used, with placeholders, so SQL
567             injection attacks will not work, but it's easier to illustrate as though the
568             values were interpolated directly. Don't worry, they're not.)
569              
570             With the same idea in mind, you can check if a value is NULL with:
571              
572             { foo => undef }
573              
574             This will be correctly rewritten to C.
575              
576             You can pass an empty hashref if you want all rows, e.g.:
577              
578             database->quick_select('mytable', {});
579              
580             ... is the same as C<"SELECT * FROM 'mytable'">
581              
582             If you pass in an arrayref as the value, you can get a set clause as in the
583             following example:
584              
585             { foo => [ 'bar', 'baz', 'quux' ] }
586              
587             ... it's the same as C
588              
589             If you need additional flexibility, you can build fairly complex where
590             clauses by passing a hashref of condition operators and values as the
591             value to the column field key.
592              
593             Currently recognized operators are:
594              
595             =over
596              
597             =item 'like'
598              
599             { foo => { 'like' => '%bar%' } }
600              
601             ... same as C
602              
603             =item 'ilike'
604              
605             Postgres-specific - same as 'like', but case-insensitive.
606              
607             =item 'gt' / 'ge'
608              
609             'greater than' or 'greater or equal to'
610            
611             { foo => { 'ge' => '42' } }
612              
613             ... same as C= '42'>
614              
615             =item 'lt' / 'le'
616              
617             'less than' or 'less or equal to'
618              
619             { foo => { 'lt' => '42' } }
620              
621             ... same as C '42'>
622              
623             =item 'eq' / 'ne' / 'is'
624              
625             'equal' or 'not equal' or 'is'
626              
627             { foo => { 'ne' => 'bar' } }
628              
629             ... same as C
630              
631             =back
632              
633             You can also include a key named 'not' with a true value in the hashref
634             which will (attempt) to negate the other operator(s).
635              
636             { foo => { 'like' => '%bar%', 'not' => 1 } }
637              
638             ... same as C
639              
640             If you use undef as the value for an operator hashref it will be
641             replaced with 'NULL' in the query.
642              
643             If that's not flexible enough, you can pass in your own scalar WHERE clause
644             string B there's no automatic sanitation on that - if you suffer
645             from a SQL injection attack - don't blame me!
646             Don't forget to use C/C on it then.
647              
648             =head1 AUTHOR
649              
650             David Precious C< <> >
651              
652             =head1 ACKNOWLEDGEMENTS
653              
654             See L
655              
656             =head1 SEE ALSO
657              
658             L and L
659              
660             L and L
661              
662             L
663              
664             =head1 LICENSE AND COPYRIGHT
665              
666             Copyright 2016 David Precious.
667              
668             This program is free software; you can redistribute it and/or modify it
669             under the terms of the the Artistic License (2.0). You may obtain a
670             copy of the full license at:
671              
672             L
673              
674             Any use, modification, and distribution of the Standard or Modified
675             Versions is governed by this Artistic License. By using, modifying or
676             distributing the Package, you accept this license. Do not use, modify,
677             or distribute the Package, if you do not accept this license.
678              
679             If your Modified Version has been derived from a Modified Version made
680             by someone other than you, you are nevertheless required to ensure that
681             your Modified Version complies with the requirements of this license.
682              
683             This license does not grant you the right to use any trademark, service
684             mark, tradename, or logo of the Copyright Holder.
685              
686             This license includes the non-exclusive, worldwide, free-of-charge
687             patent license to make, have made, use, er to sell, sell, import and
688             otherwise transfer the Package with respect to any patent claims
689             licensable by the Copyright Holder that are necessarily infringed by the
690             Package. If you institute patent litigation (including a cross-claim or
691             counterclaim) against any party alleging that the Package constitutes
692             direct or contributory patent infringement, then this Artistic License
693             to you shall terminate on the date that such litigation is filed.
694              
695             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
696             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
697             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
698             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
699             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
700             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
701             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
702             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
703              
704             =cut
705              
706             1;
707             __END__