File Coverage

blib/lib/Persistence/ValueGenerator/TableGenerator.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package Persistence::ValueGenerator::TableGenerator;
2              
3 5     5   483199 use strict;
  5         11  
  5         194  
4 5     5   31 use warnings;
  5         11  
  5         167  
5 5     5   25 use vars qw(@EXPORT_OK %EXPORT_TAGS $VERSION);
  5         11  
  5         373  
6 5     5   31 use base qw (Exporter Persistence::ValueGenerator);
  5         8  
  5         2540  
7              
8 5     5   36 use Abstract::Meta::Class ':all';
  5         9  
  5         717  
9 5     5   2357 use Persistence::Entity;
  0            
  0            
10              
11             $VERSION = 0.02;
12              
13             @EXPORT_OK = qw(table_generator);
14             %EXPORT_TAGS = (all => \@EXPORT_OK);
15              
16              
17             =head1 NAME
18              
19             Persistence::ValueGenerator::TableGenerator - Unique value generator based on database table
20              
21             =cut
22              
23             =head1 CLASS HIERARCHY
24              
25             Persistence::ValueGenerator
26             |
27             +----Persistence::ValueGenerator::TableGenerator
28              
29             =head1 SYNOPSIS
30              
31             use Persistence::ValueGenerator::TableGenerator;
32              
33             my $generator = Persistence::ValueGenerator::TableGenerator->new(
34             name => 'pk_generator',
35             entity_manager_name => $entity_manager_name,
36             table => 'primary_key_generator',
37             schema => '',
38             primary_key_column_name => 'pk_column',
39             primary_key_column_value => 'empno',
40             value_column => 'value_column',
41             allocation_size => 20,
42             );
43              
44             my $seq = $generator->nextval;
45              
46             or
47              
48             use Persistence::ValueGenerator::TableGenerator ':all';
49              
50             my $generator = table_generator 'pk_generator' => (
51             entity_manager_name => $entity_manager_name,
52             table => 'primary_key_generator',
53             schema => '',
54             primary_key_column_name => 'pk_column',
55             primary_key_column_value => 'empno',
56             value_column => 'value_column',
57             allocation_size => 20,
58             );
59              
60             =head1 DESCRIPTION
61              
62             Represents sequence generator that uses table name
63             The primary_key_column_name holds a value that is used to match the primary key you are generating for.
64             The value_column holds the value of the counter.
65              
66             use Persistence::ValueGenerator::TableGenerator;
67             use Persistence::Entity::Manager;
68              
69             my $entity_manager = Persistence::Entity::Manager->new(connection_name => 'my_connection');
70             my $generator = Persistence::ValueGenerator::TableGenerator->new(
71             entity_manager => $entity_manager,
72             name => 'pk_generator',
73             table => 'seq_generator',
74             schema => '',
75             primary_key_column_name => 'pk_column',
76             primary_key_column_value => 'empno',
77             value_column => 'value_column',
78             allocation_size => 20,
79             );
80              
81             # for that instance you need the following table
82             # CREATE TABLE seq_generator(pk_column VARCHAR2(30), value_column double)
83             # CREATE emp(empno number, ename varchar2(100), deptno number);
84              
85             =head1 EXPORT
86              
87             table_generator by ':all' tag.
88              
89             =head2 ATTRIBUTES
90              
91             =over
92              
93             =item table
94              
95             Table name of the generator table.
96              
97             =cut
98              
99             has '$.table' => (required => 1, default => 'custom_pk_generator');
100              
101              
102             =item schema
103              
104             Schema name of the generator table.
105              
106             =cut
107              
108             has '$.schema';
109              
110              
111             =item primary_key_column_name
112              
113             Name of the column that identifies the specific table primary key you are generating for.
114              
115             =cut
116              
117             has '$.primary_key_column_name' => (required => 1, default => 'pk_column');
118              
119              
120             =item primary_key_column_value
121              
122             Used to match up with the primary key you are generating for.
123              
124             =cut
125              
126              
127             has '$.primary_key_column_value' => (required => 1);
128              
129              
130             =item value_column
131              
132             Specifies the name of the column that will hold the counter for the generated primary key.
133              
134             =cut
135              
136             has '$.value_column' => (required => 1);
137              
138            
139             =back
140              
141             =head2 METHODS
142              
143             =over
144              
145             =item initialise
146              
147             =cut
148              
149            
150             =item initialise
151              
152             =cut
153              
154             sub initialise {
155             my ($self) = @_;
156             $self->initailise_entity;
157             $self->SUPER::initialise();
158             }
159            
160              
161             =item initailise_entity
162              
163             =cut
164              
165             sub initailise_entity {
166             my ($self) = @_;
167             my $entity_manager = $self->entity_manager;
168             return if ($entity_manager->entity($self->id));
169             $self->entity_manager->add_entities(
170             Persistence::Entity->new(
171             id => $self->id,
172             name => $self->table,
173             schema => $self->schema,
174             primary_key => [$self->primary_key_column_name],
175             columns => [
176             Persistence::Entity::sql_column(name => $self->value_column),
177             Persistence::Entity::sql_column(name => $self->primary_key_column_name),
178             ],
179             alias => 't',
180             )
181             );
182             }
183            
184              
185             =item id
186              
187             returns schma.table as id
188              
189             =cut
190              
191             sub id {
192             my $self = shift;
193             my $schema = $self->schema;
194             ($schema ? $schema . "." : "") . $self->table;
195             }
196              
197              
198              
199              
200             =item retrieve_next_value
201              
202             Checks current seq number in database, increments counter by $self->allocation_size + 1
203              
204             =cut
205              
206             sub retrieve_next_value {
207             my ($self) = @_;
208             my $entity = $self->entity_manager->entity($self->id);
209             my ($record) = $entity->lock(undef, $self->primary_key_column_name => $self->primary_key_column_value);
210             my $seq = $record ? $record->{$self->value_column} : undef;
211             if ($seq) {
212             $entity->update({
213             $self->value_column => ($seq + ($self->allocation_size || 1)),
214             }, {
215             $self->primary_key_column_name => $self->primary_key_column_value
216             }
217             );
218             return $seq;
219            
220             } else {
221             $entity->insert(
222             $self->value_column => (($self->allocation_size || 1) + 1),
223             $self->primary_key_column_name => $self->primary_key_column_value
224             );
225             return 1;
226             }
227             }
228              
229              
230             =item table_generator
231              
232             Creates a new instance of Persistence::ValueGenerator::TableGenerator
233              
234             =cut
235              
236             sub table_generator {
237             my $name = shift;
238             __PACKAGE__->new(@_, name => $name);
239             }
240              
241             1;
242              
243             __END__