File Coverage

blib/lib/Acme/BeyondPerl/ToSQL.pm
Criterion Covered Total %
statement 83 111 74.7
branch 17 28 60.7
condition n/a
subroutine 28 41 68.2
pod 0 22 0.0
total 128 202 63.3


line stmt bran cond sub pod time code
1             package Acme::BeyondPerl::ToSQL;
2              
3 1     1   271480 use strict;
  1         2  
  1         30  
4 1     1   5 use DBI;
  1         1  
  1         29  
5 1     1   5 use Carp;
  1         5  
  1         2451  
6              
7             our $VERSION = 0.01;
8             our $DEBUG = 0;
9              
10             my $Dbh; # database handle
11             my $Type; # rdbm type
12              
13             END {
14 1     1   387 $Dbh->disconnect()
15             }
16              
17             ##############################################################################
18              
19             sub import {
20 1     1   12 my $class = shift;
21 1 50       6 my %hash = %{ $_[0] } if(@_ == 1);
  1         5  
22 1 50       4 my ($dsn, $user, $pass, $opt) = (@_ > 1) ? @_ : @{$hash{dbi}};
  1         3  
23              
24 1 50       4 _connect($dsn, $user, $pass, $opt) unless($Dbh);
25              
26 1         6 _overload();
27              
28 1         5 overload::constant (
29             integer => \&_integer_handler,
30             float => \&_float_handler,
31             );
32              
33 1 50       35 if(defined $hash{debug}){ $DEBUG = $hash{debug}; }
  1         20  
34              
35             }
36              
37              
38             my $OPs = {
39             '+' => sub { shift->add(@_) },
40             '-' => sub { shift->sub(@_) },
41             '*' => sub { shift->mul(@_) },
42             '/' => sub { shift->div(@_) },
43             '%' => sub { shift->mod(@_) },
44             '**' => sub { shift->pow(@_) },
45             'log' => sub { shift->log(@_) },
46             'sqrt' => sub { shift->sqrt(@_)},
47             'abs' => sub { shift->abs(@_) },
48             'cos' => sub { shift->cos(@_) },
49             'sin' => sub { shift->sin(@_) },
50             'exp' => sub { shift->exp(@_) },
51             'atan2'=> sub { shift->atan2(@_) },
52             '<<' => sub { shift->lshift(@_) },
53             '>>' => sub { shift->rshift(@_) },
54             '&' => sub { shift->and(@_) },
55             '|' => sub { shift->or(@_) },
56             '^' => sub { shift->xor(@_) },
57             };
58              
59              
60 0     0 0 0 sub ops { return $OPs; }
61              
62 0     0 0 0 sub Type { $Type; }
63              
64             ##############################################################################
65              
66             sub _connect {
67 1     1   2 my ($dsn, $user, $pass, $opts) = @_;
68              
69 1 50       7 $Dbh = DBI->connect($dsn, $user, $pass, $opts) or die $!;
70              
71 1         20817 $Type = ($dsn =~ /dbi:(\w+)/)[0];
72             }
73              
74              
75             sub _overload {
76 1     1   4 my $mod = __PACKAGE__ . '::' . $Type;
77              
78 1         113 eval qq| require $mod |;
79 1 50       5 if($@){ croak "Can't load $mod."; }
  0         0  
80              
81 1         4 my $ops = $mod->ops;
82             my %operators = (
83             nomethod => \&_nomethod,
84 4     4   106 '""' => sub { ${$_[0]} },
  4         32  
85 4     4   212 '<=>' => sub { ${$_[0]} <=> ${$_[1]} },
  4         7  
  4         18  
86 1     1   2 '0+' => sub { ${$_[0]} },
  1         3  
87 2     2   4 'bool' => sub { ${$_[0]} },
  2         15  
88 20     20   2560 'cmp' => sub { ${$_[0]} cmp ${$_[1]} },
  20         37  
  20         193  
89 1         9 %{ $ops }
  1         14  
90             );
91              
92 1     1   1964 eval q| use overload %operators |;
  1         1324  
  1         10  
  1         101  
93 1 50       233 if($@){ die $@; }
  0         0  
94              
95             }
96              
97              
98             sub _integer_handler {
99 56     56   184 my ($ori, $interp, $contect) = @_;
100 56         3013 return bless \$interp, __PACKAGE__ . "::$Type\::__Integer";
101             }
102              
103             sub _float_handler {
104 30     30   1581 my ($ori, $interp, $contect) = @_;
105 30         742 return bless \$interp, __PACKAGE__ . "::$Type\::__Float";
106             }
107              
108              
109             ##############################################################################
110             # Use From Objects
111             ##############################################################################
112              
113             sub _calc_by_rdbm {
114 21 50   21   45 if($DEBUG){ print "$_[0]\n"; }
  0         0  
115 21         172 _float_handler( undef, $Dbh->selectrow_array($_[0]) );
116             }
117              
118              
119             sub _nomethod {
120 0     0   0 my ($x, $y, $swap, $op) = @_;
121 0         0 croak "This operator '$op' is not implemented in $Type";
122             }
123              
124              
125             sub _get_args {
126 15     15   32 my ($x, $y, $swap) = @_;
127 15 100       345 if($swap){ ($x, $y) = ($y, $x) }
  1         4  
128 15 100       91 $x = $x->as_sql if(UNIVERSAL::can($x,'as_sql'));
129 15 100       80 $y = $y->as_sql if(UNIVERSAL::can($y,'as_sql'));
130 15         44 return ($x,$y);
131             }
132              
133             sub _get_args_as_bits {
134 6     6   9 my ($x, $y, $swap) = @_;
135 6 50       14 if($swap){ ($x, $y) = ($y, $x) }
  0         0  
136 6 50       32 $x = $x->as_bit if(UNIVERSAL::can($x,'as_sql'));
137 6 50       24 $y = $y->as_bit if(UNIVERSAL::can($y,'as_sql'));
138 6         88 return ($x,$y);
139             }
140              
141 0     0 0 0 sub as_sql { ${$_[0]} }
  0         0  
142              
143 12     12 0 1430 sub as_bit { ${$_[0]} }
  12         29  
144              
145             ##############################################################################
146             # OPERATORS
147             ##############################################################################
148              
149             sub add {
150 4     4 0 12 my ($x, $y) = _get_args(@_);
151 4         17 _calc_by_rdbm("SELECT $x + $y");
152             }
153              
154              
155             sub sub {
156 7     7 0 17 my ($x, $y) = _get_args(@_);
157 7         24 _calc_by_rdbm("SELECT $x - $y");
158             }
159              
160              
161             sub mul {
162 2     2 0 7 my ($x, $y) = _get_args(@_);
163 2         10 _calc_by_rdbm("SELECT $x * $y");
164             }
165              
166              
167             sub div {
168 1     1 0 4 my ($x, $y) = _get_args(@_);
169 1         6 _calc_by_rdbm("SELECT $x / $y");
170             }
171              
172              
173             sub mod {
174 1     1 0 3 my ($x, $y) = _get_args(@_);
175 1         4 _calc_by_rdbm("SELECT $x % $y");
176             }
177              
178              
179             sub pow {
180 0     0 0 0 my ($x, $y) = _get_args(@_);
181 0         0 _calc_by_rdbm("SELECT pow($x, $y)");
182             }
183              
184             sub abs {
185 0     0 0 0 my ($x) = _get_args(@_);
186 0         0 _calc_by_rdbm("SELECT abs($x)");
187             }
188              
189             sub log {
190 0     0 0 0 my ($x) = _get_args(@_);
191 0         0 _calc_by_rdbm("SELECT ln($x)");
192             }
193              
194             sub exp {
195 0     0 0 0 my ($x) = _get_args(@_);
196 0         0 _calc_by_rdbm("SELECT exp($x)");
197             }
198              
199             sub sqrt {
200 0     0 0 0 my ($x) = _get_args(@_);
201 0         0 _calc_by_rdbm("SELECT sqrt($x)");
202             }
203              
204             sub sin {
205 0     0 0 0 my ($x) = _get_args(@_);
206 0         0 _calc_by_rdbm("SELECT sin($x)");
207             }
208              
209             sub cos {
210 0     0 0 0 my ($x) = _get_args(@_);
211 0         0 _calc_by_rdbm("SELECT cos($x)");
212             }
213              
214             sub atan2 {
215 0     0 0 0 my ($x, $y) = _get_args(@_);
216 0         0 _calc_by_rdbm("SELECT atan2($x, $y)");
217             }
218              
219             sub lshift {
220 1     1 0 5 my ($x, $y) = _get_args_as_bits(@_);
221 1         4 _calc_by_rdbm("SELECT $x << $y");
222             }
223              
224             sub rshift {
225 1     1 0 3 my ($x, $y) = _get_args_as_bits(@_);
226 1         4 _calc_by_rdbm("SELECT $x >> $y");
227             }
228              
229             sub and {
230 2     2 0 17 my ($x, $y) = _get_args_as_bits(@_);
231 2         10 _calc_by_rdbm("SELECT $x & $y");
232             }
233              
234             sub or {
235 2     2 0 5 my ($x, $y) = _get_args_as_bits(@_);
236 2         6 _calc_by_rdbm("SELECT $x | $y");
237             }
238              
239             sub xor {
240 0     0 0   my ($x, $y) = _get_args_as_bits(@_);
241 0           _calc_by_rdbm("SELECT $x ^ $y");
242             }
243              
244             ##############################################################################
245             1;
246             __END__