File Coverage

blib/lib/SQL/Query/Limit/PostgreSQL.pm
Criterion Covered Total %
statement 30 38 78.9
branch 0 6 0.0
condition 1 3 33.3
subroutine 10 12 83.3
pod 5 5 100.0
total 46 64 71.8


line stmt bran cond sub pod time code
1             package SQL::Query::Limit::PostgreSQL;
2              
3 2     2   4494 use warnings;
  2         5  
  2         65  
4 2     2   11 use strict;
  2         4  
  2         150  
5 2     2   11 use vars qw($VERSION);
  2         3  
  2         105  
6              
7             $VERSION = '0.02';
8              
9 2     2   10 use Abstract::Meta::Class ':all';
  2         3  
  2         378  
10 2     2   12 use SQL::Entity::Column ':all';
  2         3  
  2         191  
11 2     2   11 use SQL::Entity::Condition ':all';
  2         4  
  2         224  
12 2     2   11 use base 'SQL::Entity';
  2         5  
  2         950  
13              
14             =head1 NAME
15              
16             SQL::Query::Limit::PostgreSQL - LIMIT emulation for PostgreSQL database.
17              
18             =cut
19              
20             =head1 NAME
21              
22             SQL::Query::Limit::PostgreSQL
23              
24             =head1 SYNOPSIS
25              
26             use SQL::Query::Limit::PostgreSQL;
27              
28             =head1 DESCRIPTION
29              
30             SQL navigation for PostgreSQL.
31              
32             =head2 EXPORT
33              
34             None.
35              
36             =head2 ATTRIBUTES
37              
38             =over
39              
40             =item the_rownum
41              
42             =cut
43              
44             has '$.the_rownum';
45              
46             =back
47              
48             =head2 METHODS
49              
50             =over
51              
52             =item sql_definition
53              
54             =cut
55              
56             {
57             my %SQL = (
58             find_sequence => "SELECT 1 AS has_seq FROM pg_class JOIN pg_authid ON pg_class.relowner = pg_authid.oid
59             WHERE pg_class.relkind = 'S' AND pg_class.relname = ? AND pg_authid.rolname = ?",
60             );
61              
62              
63             =item sql_defintion
64              
65             Retuns sql defintion.
66             Takes sql statement name.
67              
68             =cut
69              
70             sub sql_defintion {
71 0     0 1 0 my ($self, $name) = @_;
72 0         0 $SQL{$name};
73             }
74             }
75              
76              
77             =item query
78            
79             =cut
80              
81             sub query {
82 1     1 1 13 my ($self, $offset, $limit, $requested_columns, $condition) = @_;
83 1         7 my ($sql, $bind_variables) = $self->SUPER::query($requested_columns, $condition);
84 1         3 $sql = "SELECT " . $self->alias . ".*," . $self->the_rownum_column->as_string
85             . "\nFROM (\n" . $sql . ") " . $self->alias
86             . "\nLIMIT ? OFFSET ?";
87 1         9 push @$bind_variables, $limit, ($offset - 1);
88 1         3 ($sql, $bind_variables);
89             }
90              
91            
92             =item the_rownum_column
93              
94             =cut
95              
96             sub the_rownum_column {
97 1     1 1 8 my ($self) = @_;
98 1         3 my $the_rownum = $self->the_rownum;
99 1   33     10 $the_rownum ||= $self->the_rownum(SQL::Entity::Column->new(name => "nextval('". $self->sequence_name . "')", id => 'the_rownum'));
100             }
101              
102              
103             =item sequence_name
104              
105             =cut
106              
107             sub sequence_name {
108 1     1 1 5 'rownum';
109             }
110              
111              
112             =item query_setup
113              
114             TODO. Improve collision in threads,
115             - add ower to PLSQL
116              
117             =cut
118              
119             sub query_setup {
120 0     0 1   my ($self, $connection) = @_;
121 0           my $sequence_name = $self->sequence_name;
122 0           my $result_set = $connection->record($self->sql_defintion('find_sequence'), $sequence_name, $connection->username);
123 0 0         if ($result_set->{has_seq}) {
124 0 0         $connection->do("SELECT setval('${sequence_name}', 1);") if $result_set->{has_seq};
125             } else {
126 0 0         $connection->do("create temp sequence " . $sequence_name) unless $result_set->{has_seq};
127             }
128             }
129              
130             1;
131              
132             __END__