File Coverage

blib/lib/SQL/Object.pm
Criterion Covered Total %
statement 65 78 83.3
branch 9 14 64.2
condition 1 3 33.3
subroutine 22 25 88.0
pod 9 11 81.8
total 106 131 80.9


line stmt bran cond sub pod time code
1             package SQL::Object;
2 2     2   46082 use strict;
  2         4  
  2         74  
3 2     2   11 use warnings;
  2         3  
  2         52  
4 2     2   2135 use utf8;
  2         25  
  2         10  
5 2     2   76 use Exporter qw/import/;
  2         4  
  2         299  
6              
7             our @EXPORT_OK = qw/sql_obj sql_type/;
8              
9             use overload
10 0     0   0 '&' => sub { $_[0]->compose_and($_[1]) },
11 2     2   33 '|' => sub { $_[0]->compose_or($_[1]) },
12 1     1   6 '+' => sub { $_[0]->join($_[1]) },
13 0     0   0 '""' => sub { $_[0]->as_sql },
14 2         23 fallback => 1
15 2     2   3336 ;
  2         2202  
16              
17             our $VERSION = '0.01';
18              
19             sub sql_obj {
20 5     5 0 750 my ($sql, $args) = @_;
21              
22 5         9 my $bind;
23 5 100       20 if (ref($args) eq 'HASH') {
24 1         2 my %named_bind = %{$args};
  1         5  
25 1         8 $sql =~ s{:(\w+)}{
26 1 50       6 Carp::croak("$1 does not exists in hash") if !exists $named_bind{$1};
27 1 50 33     13 if ( ref $named_bind{$1} && ref $named_bind{$1} eq "ARRAY" ) {
28 0         0 push @$bind, @{ $named_bind{$1} };
  0         0  
29 0         0 my $tmp = join ',', map { '?' } @{ $named_bind{$1} };
  0         0  
  0         0  
30 0         0 "($tmp)";
31             } else {
32 1         4 push @$bind, $named_bind{$1};
33 1         5 '?'
34             }
35             }ge;
36             }
37             else {
38 4 50       19 $bind = ref($args) eq 'ARRAY' ? $args : [$args];
39             }
40              
41 5         25 SQL::Object->new(sql => $sql, bind => $bind);
42             }
43              
44             sub sql_type {
45 1     1 1 2706 my ($value_ref, $type) = @_;
46 1         10 SQL::Object::Type->new(value_ref => $value_ref, type => $type);
47             }
48              
49             sub new {
50 5     5 1 10 my $class = shift;
51 5 50       24 my %args = @_==1 ? %{$_[0]} : @_;
  0         0  
52 5         38 bless {%args}, $class;
53             }
54              
55             sub _compose {
56 4     4   8 my ($self, $op, $sql, $bind) = @_;
57              
58 4         15 $self->{sql} = $self->{sql} . " $op " . $sql;
59 4         8 $self->{bind} = [@{$self->{bind}}, @$bind];
  4         12  
60 4         17 $self;
61             }
62              
63             sub and {
64 1     1 1 4 my ($self, $sql, @bind) = @_;
65 1         4 $self->_compose('AND', $sql, \@bind);
66             }
67              
68             sub or {
69 3     3 1 9 my ($self, $sql, @bind) = @_;
70 3         11 $self->add_parens->_compose('OR', $sql, \@bind);
71             }
72              
73             sub join {
74 1     1 0 3 my ($self, $other) = @_;
75 1         5 $self->{sql} = $self->{sql} . $other->{sql};
76 1         2 $self->{bind} = [@{$self->{bind}}, @{$other->{bind}}];
  1         2  
  1         5  
77 1         3 $self;
78             }
79              
80             sub compose_and {
81 0     0 1 0 my ($self, $other) = @_;
82 0         0 $self->and($other->{sql}, @{$other->{bind}});
  0         0  
83             }
84              
85             sub compose_or {
86 2     2 1 5 my ($self, $other) = @_;
87 2         36 $self->or($other->add_parens->as_sql, @{$other->{bind}});
  2         571  
88             }
89              
90             sub add_parens {
91 5     5 1 7 my $self = shift;
92 5         16 $self->{sql} = '('.$self->{sql}.')';
93 5         19 $self;
94             }
95              
96 10     10 1 107 sub as_sql { $_[0]->{sql} }
97 6 100   6 1 23 sub bind { wantarray ? @{$_[0]->{bind}} : $_[0]->{bind} }
  5         46  
98              
99             package # hide from PAUSE
100             SQL::Object::Type;
101              
102             sub new {
103 1     1   2 my $class = shift;
104 1 50       7 my %args = @_==1 ? %{$_[0]} : @_;
  0         0  
105 1         9 bless {%args}, $class;
106             }
107              
108 1     1   2 sub value { ${$_[0]->{value_ref}} }
  1         6  
109 1     1   19 sub value_ref { $_[0]->{value_ref} }
110 1     1   6 sub type { $_[0]->{type} }
111              
112             1;
113             __END__