File Coverage

blib/lib/DBD/Amazon.pm
Criterion Covered Total %
statement 18 30 60.0
branch 0 4 0.0
condition n/a
subroutine 7 9 77.7
pod n/a
total 25 43 58.1


line stmt bran cond sub pod time code
1             #
2             # Copyright (c) 2005, Presicient Corp., USA
3             #
4             # Permission is granted to use this software according to the terms of the
5             # Artistic License, as specified in the Perl README file,
6             # with the exception that commercial redistribution, either
7             # electronic or via physical media, as either a standalone package,
8             # or incorporated into a third party product, requires prior
9             # written approval of the author.
10             #
11             # This software is distributed in the hope that it will be useful,
12             # but WITHOUT ANY WARRANTY; without even the implied warranty of
13             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14             #
15             # Presicient Corp. reserves the right to provide support for this software
16             # to individual sites under a separate (possibly fee-based)
17             # agreement.
18             #
19             # History:
20             #
21             # 2005-Jan-27 D. Arnold
22             # Coded.
23             #
24              
25             require DynaLoader;
26             require DBD::File;
27             require IO::File;
28              
29             package DBD::Amazon;
30 1     1   23804 use vars qw(@ISA $VERSION $drh $err $errstr $sqlstate);
  1         2  
  1         117  
31              
32             our @ISA = qw(DBD::File);
33              
34 1     1   623 use SQL::Amazon::StorageEngine;
  1         3  
  1         39  
35              
36 1     1   9 use Exporter;
  1         1  
  1         62  
37 1     1   6 use base qw(Exporter);
  1         1  
  1         104  
38              
39             BEGIN {
40 1     1   3 our @EXPORT = ();
41 1         16 our @EXPORT_OK = qw($amzn_engine);
42             }
43              
44 1     1   6 use strict;
  1         2  
  1         272  
45              
46             our $amzn_engine;
47              
48             our $VERSION = '0.10';
49              
50             our $err = 0;
51             our $errstr = '';
52             our $sqlstate = '';
53             our $drh = undef;
54              
55             my $installed = undef;
56              
57             sub driver {
58 0 0   0     return $drh if $drh;
59 0           my ($class, $attr) = @_;
60              
61 0           $attr->{Attribution} = 'DBD::Amazon by Presicient Corp.';
62 0           my $this = $class->SUPER::driver($attr);
63 0           $amzn_engine = SQL::Amazon::StorageEngine->new();
64 0 0         unless ($DBD::Amazon::installed) {
65             }
66              
67 0           DBI->trace_msg("DBD::Amazon v.$VERSION loaded on $^O\n", 1);
68 0           $drh->{_connections} = {};
69              
70 0           $this;
71             }
72              
73             sub CLONE {
74 0     0     undef $drh;
75             }
76              
77             1;
78              
79             package DBD::Amazon::dr;
80              
81 1     1   811 use SQL::Amazon::Parser;
  0            
  0            
82             use DBD::Amazon qw($amzn_engine);
83             use vars qw(@ISA);
84              
85             @DBD::Amazon::dr::ISA = qw(DBD::File::dr);
86              
87             use strict;
88              
89             our $imp_data_size = 0;
90              
91             our %valid_attrs = qw(
92             amzn_affiliate_id 0
93             amzn_strict 1
94             amzn_rate_limit 1
95             amzn_max_pages 20
96             amzn_locale us
97             amzn_resp_group Large
98             );
99              
100             our %valid_locales = qw(
101             us 1
102             uk 1
103             de 1
104             fr 1
105             jp 1
106             ca 1
107             );
108              
109             sub connect {
110             my ($drh, $dsn, $user, $passwd, $attrs) = @_;
111             return $drh->DBI::set_err(-1, 'No Amazon user ID provided.', 'S1000')
112             unless (defined($user) && ($user ne ''));
113              
114             $attrs = { } unless $attrs;
115             foreach (keys %$attrs) {
116             return $drh->DBI::set_err(-1, "Unknown attribute $_", 'S1000')
117             if (/^amzn_(\w+)$/ && (! $valid_attrs{$_}));
118             }
119             foreach (keys %valid_attrs) {
120             $attrs->{$_} = $valid_attrs{$_}
121             unless defined($attrs->{$_});
122             }
123             return $drh->DBI::set_err(-1, "Invalid locale attribute $$attrs{amzn_locale}", 'S1000')
124             unless $valid_locales{$attrs->{amzn_locale}};
125              
126             my $dbh = $drh->DBD::File::dr::connect($dsn, $user, $passwd, $attrs);
127              
128             return DBI::set_err(-1, 'Cannot create connection handle.', 'S1000')
129             unless $dbh;
130              
131             $dbh->{amzn_parser} = SQL::Amazon::Parser->new();
132             return DBI::set_err(-1, 'Cannot create parser for Amazon dialect.', 'S1000')
133             unless $dbh->{amzn_parser};
134              
135             $dbh->{Active} = 1;
136             return $dbh;
137             }
138             sub data_sources {
139             my($drh, $driver_name) = @_;
140             return '';
141             }
142              
143             sub disconnect_all {
144             }
145              
146             sub DESTROY {
147             }
148              
149             1;
150              
151              
152             package DBD::Amazon::db;
153              
154             use SQL::Amazon::Statement;
155             use DBD::Amazon qw($amzn_engine);
156              
157             @DBD::Amazon::db::ISA = qw(DBD::File::db);
158              
159             our $imp_data_size = 0;
160              
161             our %valid_attrs = qw(
162             amzn_strict 1
163             amzn_max_pages 20
164             amzn_resp_group Large
165             );
166              
167             use strict;
168              
169             sub prepare {
170             my ($dbh, $sql, $attrs) = @_;
171            
172             if ($attrs) {
173             foreach (keys %$attrs) {
174             next unless /^amzn_/;
175            
176             return $dbh->set_err(-1, "Unknown statement attribute $_.", 'S1000')
177             unless $valid_attrs{$_};
178             }
179             }
180             my $sth = DBI::_new_sth($dbh, {'Statement' => $sql});
181              
182             return DBI::set_err(-1, 'Cannot create statement handle.', 'S1000')
183             unless $sth;
184             $ENV{DBD_AMZN_DEBUG} = ($dbh->{TraceLevel} & 12);
185             my $stmt = SQL::Amazon::Statement->new($sql, $dbh->{amzn_parser},
186             $amzn_engine);
187             undef $sth,
188             return DBI::set_err($dbh, 1, $stmt->errstr, 'S1000')
189             if $stmt->errstr;
190             my $command = $stmt->command();
191             undef $sth,
192             return DBI::set_err($dbh, -1, "$command statements not supported.", 'S1000')
193             if (($command eq 'CREATE') || ($command eq 'DROP'));
194              
195             my @tables = $stmt->tables();
196             foreach (0..@tables) {
197             undef $sth,
198             return DBI::set_err($dbh, -1,
199             "$command statements not supported on table $_.", 'S1000')
200             if (($command ne 'SELECT') &&
201             ($amzn_engine->is_readonly($_)));
202             }
203             $sth->STORE('f_stmt', $stmt);
204             $sth->STORE('f_params', []);
205             $sth->STORE('NUM_OF_PARAMS', scalar($stmt->params()));
206             $sth->STORE($_, ($attrs && $attrs->{$_}) ?
207             $attrs->{$_} : $dbh->{$_} ? $dbh->{$_} : $valid_attrs{$_})
208             foreach (keys %valid_attrs);
209             $sth->{TraceLevel} = $dbh->{TraceLevel};
210              
211             return $sth;
212             }
213              
214             sub disconnect {
215             my $dbh = shift;
216              
217             $dbh->STORE('Active', 0);
218             return 1;
219             }
220              
221             sub table_info ($) {
222             my($dbh) = @_;
223             my $sth = $dbh->prepare(
224             'SELECT TABLE_CAT,
225             TABLE_SCHEM,
226             TABLE_NAME,
227             TABLE_TYPE,
228             REMARKS
229             FROM SYSSCHEMA');
230             return ($sth && $sth->execute) ? $sth : undef;
231             }
232              
233             sub DESTROY {
234             my $dbh = shift;
235              
236             $dbh->STORE('Active', 0);
237             }
238              
239             sub type_info_all ($) {
240             [
241             { TYPE_NAME => 0,
242             DATA_TYPE => 1,
243             PRECISION => 2,
244             LITERAL_PREFIX => 3,
245             LITERAL_SUFFIX => 4,
246             CREATE_PARAMS => 5,
247             NULLABLE => 6,
248             CASE_SENSITIVE => 7,
249             SEARCHABLE => 8,
250             UNSIGNED_ATTRIBUTE=> 9,
251             MONEY => 10,
252             AUTO_INCREMENT => 11,
253             LOCAL_TYPE_NAME => 12,
254             MINIMUM_SCALE => 13,
255             MAXIMUM_SCALE => 14,
256             },
257             [ 'VARCHAR', DBI::SQL_VARCHAR(),
258             undef, "'","'", undef,0, 1,1,0,0,0,undef,1,999999
259             ],
260             [ 'CHAR', DBI::SQL_CHAR(),
261             undef, "'","'", undef,0, 1,1,0,0,0,undef,1,999999
262             ],
263             [ 'DECIMAL', DBI::SQL_DECIMAL(),
264             31, "", "", undef,0, 0,1,0,0,0,undef,0, 31
265             ],
266             [ 'INTEGER', DBI::SQL_INTEGER(),
267             undef, "", "", undef,0, 0,1,0,0,0,undef,0, 0
268             ],
269             [ 'FLOAT', DBI::SQL_FLOAT(),
270             undef, "", "", undef,0, 0,1,0,0,0,undef,0, 0
271             ],
272             ]
273             }
274              
275             1;
276              
277             package DBD::Amazon::st;
278             our $imp_data_size = 0;
279             @DBD::Amazon::st::ISA = qw(DBD::File::st);
280             sub execute {
281             my $sth = shift;
282             my $params;
283             if (@_) {
284             $sth->{f_params} = ($params = [@_]);
285             }
286             else {
287             $params = $sth->{f_params};
288             }
289              
290             $sth->finish
291             if $sth->{Active};
292              
293             $sth->{Active} = 1;
294              
295             $ENV{DBD_AMZN_DEBUG} = ($sth->{TraceLevel} & 12);
296              
297             my $result = $sth->{f_stmt}->execute($sth, $params);
298             return $sth->set_err(-1, $sth->{f_stmt}->errstr, 'S1000')
299             unless defined($result);
300              
301             $sth->STORE('NUM_OF_FIELDS', $sth->{f_stmt}->{NUM_OF_FIELDS})
302             if ($sth->{f_stmt}->{NUM_OF_FIELDS} && !$sth->FETCH('NUM_OF_FIELDS'));
303              
304             return $result;
305             }
306              
307             sub DESTROY ($) { undef; }
308              
309             1;
310              
311             =pod
312              
313             =head1 NAME
314              
315             DBD::Amazon- DBI driver abstraction for the Amazon E-Commerce Services API
316              
317             =head1 SYNOPSIS
318              
319             $dbh = DBI->connect('dbi:Amazon:', $amznid, undef,
320             { amzn_mode => 'books',
321             amzn_locale => 'us',
322             amzn_max_pages => 3
323             })
324             or die "Cannot connect: " . $DBI::errstr;
325             #
326             # search for some Perl DBI books
327             #
328             $sth = $dbh->prepare("
329             SELECT ASIN,
330             Title,
331             Publisher,
332             PublicationDate,
333             Author,
334             SmallImageURL,
335             URL,
336             SalesRank,
337             ListPriceAmt,
338             AverageRating
339             FROM Books
340             WHERE MATCHES ALL('Perl', 'DBI') AND
341             PublicationDate >= '2000-01-01'
342             ORDER BY SalesRank DESC,
343             ListPriceAmt ASC,
344             AverageRating DESC");
345              
346             $sth->execute or die 'Cannot execute: ' . $sth->errstr;
347              
348             print join(', ', @$row), "\n"
349             while $row = $sth->fetchrow_arrayref;
350              
351             $dbh->disconnect;
352              
353             =head1 DESCRIPTION
354              
355             DBD::Amazon provides a DBI and SQL syntax abstraction for the Amazon(R)
356             E-Commerce Services 4.0 API I ECS.
357             L. Using the REST interface, and
358             a limited SQL dialect, it provides a L-friendly interface to ECS.
359              
360             B and subject to change at
361             the whim of the author(s).
362              
363             =begin html
364              
365            

Download

366            
367             DBD-Amazon-0.10.tar.gz

368              
369             =end html
370              
371             =head2 Prerequisites
372              
373             Perl 5.8.0
374              
375             L 1.42 minimum
376              
377             L 1.14
378              
379             L 0.10 (included in this bundle)
380              
381             L 0.15
382              
383             =head2 Testing Considerations
384              
385             To run the test package, you'll need
386              
387             =over 4
388              
389             =item An Amazon ECS User ID
390              
391             An environment variable DBD_AMZN_USER must be set to an
392             Amazon ECS user ID in order to connect and execute ECS requests.
393             Registration at the Amazon Web Services site is required to acquire a user ID.
394              
395             =item An Internet Connection
396              
397             Obviously.
398              
399             =item Patience
400              
401             Some of these tests download large amounts of Amazon catalog
402             data, which can take some time (esp. since a minimum 1 second
403             delay between requests is required).
404              
405             =back
406              
407             Also, be prepared for possible intermittent 'Internal Error' reports; these
408             are problems within the Amazon ECS system, B failures in
409             DBD::Amazon itself.
410              
411             =head2 Installation
412              
413             For Unix:
414              
415             I
416              
417             cd DBD-Amazon-0.10
418             perl Makefile.PL
419             make
420             make test
421             make install
422              
423             Note that you probably need root or administrator permissions
424             to install. Refer to L for details
425             on installing in your own local directories.
426              
427             For Windows:
428              
429             I
430              
431             cd DBD-Amazon-0.10
432             perl Makefile.PL
433             nmake
434             nmake test
435             nmake install
436              
437             =head2 SQL Dialect
438              
439             DBD::Amazon supports a subset of standard SQL, and additional
440             predicate functions for keyword searches. Review L
441             and L for syntax details.
442              
443             Use C to retrieve the metadata for any of the defined
444             tables/views.
445              
446             Currently, only the following tables are defined:
447              
448             =over 4
449              
450             =item B
451              
452             =item B
453              
454             =item B
455              
456             =item B
457              
458             =item B
459              
460             =item B
461              
462             =item B
463              
464             =item B
465              
466             =item B
467              
468             =back
469              
470             =head2 Driver-specific Attributes
471              
472             =over 4
473              
474             =item amzn_locale I<(Connection attribute)>
475              
476             Sets the Amazon locale to use (i.e., the root ECS request URL).
477             Valid values are 'us', 'uk', 'de', 'fr', 'jp', 'ca' I<(Currently,
478             only us is supported)>. Default is 'us'.
479              
480             =item amzn_affiliate_id I<(Connection attribute)>
481              
482             An Amazon affiliate ID. Default none.
483              
484             =item amzn_strict I<(Connection attribute)>
485              
486             =item amzn_rate_limit I<(Connection attribute)>
487              
488             Minimum number of seconds allowed between requests. Default 1.
489             May be fractional.
490              
491             =item amzn_max_pages I<(Connection and statement attribute)>
492              
493             Maximum number of pages to return for each request. Default 20.
494              
495             =item amzn_resp_group I<(Connection and statement attribute)>
496              
497             ECS Response Group to use; can be any of 'Small', 'Medium', or 'Large';
498             default is 'Large'.
499              
500             =back
501              
502             =head1 ACKNOWLEDGEMENTS
503              
504             Many thanks to Jeff Zucker for his guidance/patience, and adding
505             some nice new features to SQL::Statement to help make DBD::Amazon
506             a reality.
507              
508             =head1 FOR MORE INFO
509              
510             L
511              
512             =head1 AUTHOR AND COPYRIGHT
513              
514             Copyright (C) 2005 by Presicient Corporation, USA
515              
516             L
517              
518             L
519              
520             Permission is granted to use this software according to the terms of the
521             Artistic License, as specified in the Perl README file,
522             with the exception that commercial redistribution, either
523             electronic or via physical media, as either a standalone package,
524             or incorporated into a third party product, requires prior
525             written approval of the author.
526              
527             This software is distributed in the hope that it will be useful,
528             but WITHOUT ANY WARRANTY; without even the implied warranty of
529             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
530              
531             Presicient Corp. reserves the right to provide support for this software
532             to individual sites under a separate (possibly fee-based)
533             agreement.
534              
535             =head1 SEE ALSO
536              
537             For help on the use of DBI, see the DBI users mailing list:
538              
539             L
540              
541             For general information on DBI see
542              
543             L
544            
545             For information about the Amazon API, see
546              
547             L
548              
549             =cut
550