File Coverage

lib/Cache/Static/DBI.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             ##
2             #
3             # Copyright 2005-2006, Brian Szymanski
4             #
5             # This file is part of Cache::Static
6             #
7             # Cache::Static is free software; you can redistribute it and/or modify
8             # it under the terms of the GNU General Public License as published by
9             # the Free Software Foundation; either version 2 of the License, or
10             # any later version.
11             #
12             # This program is distributed in the hope that it will be useful,
13             # but WITHOUT ANY WARRANTY; without even the implied warranty of
14             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15             # GNU General Public License for more details.
16             #
17             # For more information about Cache::Static, point a web browser at
18             # http://chronicle.allafrica.com/scache/ or read the
19             # documentation included with the Cache::Static distribution in the
20             # doc/ directory
21             #
22             ##
23              
24             package Cache::Static::DBI;
25              
26 1     1   2670 use DBI;
  0            
  0            
27             use Cache::Static;
28             use strict;
29              
30             sub wrap {
31             my ($class) = @_;
32             return bless { _dbh => $_[1] }, $class;
33             }
34              
35             sub prepare {
36             my ($self, $statement) = @_;
37             my $dbh_st = $self->{_dbh}->prepare($statement);
38             return Cache::Static::DBI_st->wrap($dbh_st, $statement,
39             $self->{_dbh}->{Driver}->{Name}.":".$self->{_dbh}->{Name});
40             }
41              
42             ##############################
43             ### PASS THROUGH FUNCTIONS ###
44             ##############################
45              
46             sub selectall_arrayref { my ($s, @r) = @_; $s->{_dbh}->selectall_arrayref(@r); }
47             sub selectall_hashref { my ($s, @r) = @_; $s->{_dbh}->selectall_hashref(@r); }
48             sub selectcol_arrayref { my ($s, @r) = @_; $s->{_dbh}->selectcol_arrayref(@r); }
49             sub selectcol_hashref { my ($s, @r) = @_; $s->{_dbh}->selectcol_hashref(@r); }
50             sub selectrow_array { my ($s, @r) = @_; $s->{_dbh}->selectrow_array(@r); }
51             sub selectrow_arrayref { my ($s, @r) = @_; $s->{_dbh}->selectrow_arrayref(@r); }
52             sub selectrow_hashref { my ($s, @r) = @_; $s->{_dbh}->selectrow_hashref(@r); }
53             sub quote { my ($s, @r) = @_; $s->{_dbh}->quote(@r); }
54             sub disconnect { my ($s, @r) = @_; $s->{_dbh}->disconnect(@r); }
55              
56             ######################################
57             ### AS YET UNIMPLEMENTED FUNCTIONS ###
58             ######################################
59              
60             sub do { die "do unimplemented"; }
61             sub begin_work { die "begin_work unimplemented"; }
62             sub commit { die "commit unimplemented"; }
63             sub rollback { die "rollback unimplemented"; }
64             sub prepare_cached { die "prepare_cached unimplemented"; }
65              
66             1;
67              
68             package Cache::Static::DBI_st;
69              
70             sub wrap {
71             my ($class) = @_;
72             return bless {
73             _dbi_st => $_[1],
74             _prepared_statement => $_[2],
75             _dsn => $_[3],
76             }, $class;
77             }
78              
79             sub _is_in {
80             my ($needle, @haystack) = @_;
81             map { return 1 if(lc($needle) eq lc($_)) } @haystack;
82             return 0;
83             }
84              
85             sub _update_timestamps {
86             my $spec = shift;
87             print "updating spec: $spec\n";
88             print Cache::Static::md5_path($spec)."\n";
89             Cache::Static::_write_spec_timestamp($spec);
90             }
91              
92             ### functions to implement:
93             sub execute {
94             my ($self, @rest) = @_;
95             die "execute with arguments unimplemented" if(@rest);
96              
97             my $st = $self->{_prepared_statement};
98             #TODO: statement parsing should be done in prepare()
99              
100             #look for methods that change stuff:
101             #TODO (later): LOAD DATA INFILE, REPLACE
102             $st =~ s/^\s+//;
103             my @words = split(/\s+/, $st);
104             my $cmd = shift(@words);
105             my $ro = 0;
106             my ($table);
107             if($cmd =~ /^INSERT$/i) {
108             #http://dev.mysql.com/doc/refman/5.0/en/insert.html
109             my @prefixes = qw ( LOW_PRIORITY DELAYED HIGH_PRIORITY IGNORE INTO );
110             while(_is_in($words[0], @prefixes)) { shift(@words); };
111             $table = shift(@words);
112             #TODO: deal with ON DUPLICATE KEY UPDATE col_name=expr, ... ]
113             } elsif($cmd =~ /^UPDATE$/i) {
114             #http://dev.mysql.com/doc/refman/5.0/en/update.html
115             my @prefixes = qw ( LOW_PRIORITY IGNORE );
116             while(_is_in($words[0], @prefixes)) { shift(@words); };
117             $table = shift(@words);
118             #TODO: multiple table syntax
119             } elsif($cmd =~ /^DELETE$/i) {
120             #http://dev.mysql.com/doc/refman/5.0/en/delete.html
121             my @prefixes = qw ( LOW_PRIORITY IGNORE QUICK FROM );
122             while(_is_in($words[0], @prefixes)) { shift(@words); };
123             $table = shift(@words);
124             #TODO: multiple table syntax
125             } elsif($cmd =~ /^TRUNCATE$/i) {
126             #http://dev.mysql.com/doc/refman/5.0/en/truncate.html
127             $table = shift(@words);
128             } elsif($cmd =~ /^DROP$/i) {
129             #http://dev.mysql.com/doc/refman/5.0/en/drop-table.html
130             my @prefixes = qw ( TEMPORARY TABLE );
131             while(_is_in($words[0], @prefixes)) { shift(@words); };
132             $table = shift(@words);
133             } elsif($cmd =~ /^CREATE$/i) {
134             #http://dev.mysql.com/doc/refman/5.0/en/create-table.html
135             my @prefixes = qw ( TEMPORARY TABLE );
136             while(_is_in($words[0], @prefixes)) { shift(@words); };
137             $table = shift(@words);
138             } else {
139             Cache::Static::_log(3, "got read only statement: $st");
140             $ro = 1;
141             }
142              
143             unless($ro) {
144             _update_timestamps("DBI|db|".$self->{_dsn});
145             _update_timestamps("DBI|table|".$self->{_dsn}."|$table") if($table);
146             }
147              
148             return $self->{_dbi_st}->execute();
149             }
150              
151             ##############################
152             ### PASS THROUGH FUNCTIONS ###
153             ##############################
154              
155             sub fetchrow_array { my ($s, @r) = @_; $s->{_dbi_st}->fetchrow_array(@r); }
156             sub fetchrow_arrayref { my ($s, @r) = @_; $s->{_dbi_st}->fetchrow_arrayref(@r); }
157             sub fetchrow_hashref { my ($s, @r) = @_; $s->{_dbi_st}->fetchrow_hashref(@r); }
158             sub fetchall_arrayref { my ($s, @r) = @_; $s->{_dbi_st}->fetchall_arrayref(@r); }
159             sub fetchall_hashref { my ($s, @r) = @_; $s->{_dbi_st}->fetchall_hashref(@r); }
160             sub rows { my ($s, @r) = @_; $s->{_dbi_st}->rows(@r); }
161              
162             ######################################
163             ### AS YET UNIMPLEMENTED FUNCTIONS ###
164             ######################################
165              
166             sub execute_array { die "execute_array unimplemented"; }
167             sub bind_param { die "bind_param unimplemented"; }
168             sub bind_col { die "bind_col unimplemented"; }
169             sub bind_columns { die "bind_columns unimplemented"; }
170              
171             1;
172