File Coverage

blib/lib/DBIx/OracleSequence.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             require 5.003;
2              
3             =head1 NAME
4              
5             DBIx::OracleSequence - interface to Oracle sequences via DBI.
6              
7             =head1 DESCRIPTION
8              
9             DBIx::OracleSequence is an object oriented interface to Oracle Sequences via DBI. A sequence is an Oracle database object from which multiple users may generate unique integers. You might use sequences to automatically generate primary key values. See http://technet.oracle.com/doc/server.815/a68003/01_03sch.htm#1203 for the full story on Oracle sequences. Note that you must register to access this URL, but registration is free.
10              
11             =head1 SYNOPSIS
12              
13             use DBIx::OracleSequence;
14              
15             $oracleDbh = DBI->connect("dbi:Oracle:SID", 'login', 'password');
16              
17             my $seq = new DBIx::OracleSequence($oracleDbh,'my_sequence_name');
18              
19             $seq->create(); # create a new sequence with default parms
20             $seq->incrementBy(5); # alter the seq to increment by 5
21              
22             my $nextVal = $seq->nextval(); # get the next sequence value
23             my $currval = $seq->currval(); # retrieve the current sequence value
24             $seq->print(); # print information about the sequence
25              
26             # connect to a sequence that already exists
27             my $seq2 = new DBIx::OracleSequence($oracleDbh,'preexisting_seq');
28             $seq2->print();
29             $seq2->drop(); # get rid of it
30              
31             # see if sequence name 'foo' exists
32             my $seq3 = new DBIx::OracleSequence($oracleDbh);
33             die "Doesn't exist!\n" unless $seq3->sequenceNameExists('foo');
34             $seq3->name('foo'); # attach to it
35             $seq3->print;
36              
37              
38             =head1 NOTE
39              
40             The constructor is lazy, so if you want to alter the defaults for a sequence, you need to use the maxvalue(), cache(), incrementBy(), etc. methods after constructing your sequence.
41              
42             You can access an existing Oracle sequence by calling the constructor with the existing sequence name as the second parameter. To create a new sequence, call the constructor with your new sequence name as the second parameter, then call the create() method.
43              
44             The OracleSequence object holds no state about the Oracle sequence (well, except for its name.) Instead it just serves as a passthrough to the Oracle DDL to create, drop, and set and get information about a sequence.
45              
46             =cut
47              
48             {
49             package DBIx::OracleSequence;
50 1     1   679 use strict;
  1         1  
  1         28  
51 1     1   1952 use DBD::Oracle;
  0            
  0            
52             use vars qw($VERSION);
53              
54             $VERSION = sprintf("%d.%02d", q$Revision: 0.4 $ =~ /(\d+)\.(\d+)/);
55              
56             # private helper method
57             sub _getSeqAttribute {
58             my $self = shift;
59             my $attribute = uc(shift);
60             my $seq = $self->{SEQ};
61             my $sql = "select $attribute from user_sequences where SEQUENCE_NAME='$seq'";
62             my $rv = $self->{DBH}->selectrow_array($sql);
63             }
64              
65             =head1 METHODS
66              
67             =over 4
68              
69             =item
70              
71             new($dbh,$S) - construct a new sequence with name $S
72              
73             =item
74              
75             new($dbh) - construct a new sequence without naming it yet
76              
77             =cut
78              
79             sub new {
80             my $proto = shift;
81             my $class = ref($proto) || $proto;
82             my $self = {};
83             $self->{DBH} = shift;
84             $self->{SEQ} = uc(shift) if(@_); # Oracle likes uppercase
85             bless ($self, $class);
86             return $self;
87             }
88              
89             =item
90              
91             name($S) - set the sequence name
92              
93             =item
94              
95             name() - get the sequence name
96              
97             =cut
98              
99             sub name {
100             my $self = shift;
101             $self->{SEQ} = uc(shift) if(@_);
102             $self->{SEQ};
103             }
104              
105             =item
106              
107             create() - create a new sequence. Must have already called new(). Sequence will start with 1.
108              
109             =item
110              
111             create($N) - create a new sequence. Must have already called new(). Sequence will start with $N
112              
113             =cut
114              
115             sub create {
116             my $self = shift;
117             my $seq = $self->{SEQ};
118              
119             # Carin found this bug. Pass optional sequence starting point. Defaults to 1.
120             my $startWith = shift || '1';
121             $self->{DBH}->do("create sequence $seq start with $startWith");
122             }
123              
124             =item
125              
126             currval() - return the current sequence value. Note that for a brand new sequence, Oracle requires one reference to nextval before currval is valid.
127              
128             =cut
129              
130             sub currval {
131             my $self = shift;
132             my $seq = $self->{SEQ};
133             my $rv = $self->{DBH}->selectrow_array("select $seq.currval from dual");
134             }
135              
136             =item
137              
138             nextval() - return the next sequence value
139              
140             =cut
141              
142             sub nextval {
143             my $self = shift;
144             my $seq = $self->{SEQ};
145             my $rv = $self->{DBH}->selectrow_array("select $seq.nextval from dual");
146             }
147              
148             =item
149              
150             reset() - drop and recreate the sequence with default parms
151              
152             =cut
153              
154             sub reset {
155             my $self = shift;
156             $self->drop();
157             $self->create();
158             }
159              
160             =item
161              
162             incrementBy($N) - alter sequence to increment by $N
163              
164             =item
165              
166             incrementBy() - return the current sequence's INCREMENT_BY value
167              
168             =cut
169              
170             sub incrementBy {
171             my $self = shift;
172             my $inc = shift;
173             my $seq = $self->{SEQ};
174             $self->{DBH}->do("alter sequence $seq increment by $inc") if $inc;
175             $self->_getSeqAttribute("INCREMENT_BY");
176             }
177              
178             =item
179              
180             maxvalue($N) - alter sequence setting maxvalue to $N
181              
182             =item
183              
184             maxvalue() - return the current sequence's maxvalue
185              
186             =cut
187              
188             sub maxvalue {
189             my $self = shift;
190             my $max = shift;
191             my $seq = $self->{SEQ};
192             $self->{DBH}->do("alter sequence $seq maxvalue $max") if $max;
193             $self->_getSeqAttribute("MAX_VALUE");
194             }
195              
196             =item
197              
198             minvalue($N) - alter sequence setting minvalue to $N
199              
200             =item
201              
202             minvalue() - return the current sequence's minvalue
203              
204             =cut
205              
206             sub minvalue {
207             my $self = shift;
208             my $min = shift;
209             my $seq = $self->{SEQ};
210             $self->{DBH}->do("alter sequence $seq minvalue $min") if $min;
211             $self->_getSeqAttribute("MIN_VALUE");
212             }
213              
214             =item
215              
216             cache($N) - alter sequence to cache the next $N values
217              
218             =item
219              
220             cache() - return the current sequence's cache size
221              
222             =cut
223              
224             sub cache {
225             my $self = shift;
226             my $cacheVal = shift;
227             my $seq = $self->{SEQ};
228             $self->{DBH}->do("alter sequence $seq cache $cacheVal") if $cacheVal;
229             $self->_getSeqAttribute("CACHE_SIZE");
230             }
231              
232             =item
233              
234             nocache() - alter sequence to not cache values
235              
236             =cut
237              
238             sub nocache {
239             my $self = shift;
240             my $seq = $self->{SEQ};
241             $self->{DBH}->do("alter sequence $seq nocache");
242             $self->_getSeqAttribute("CACHE_SIZE");
243             }
244              
245             =item
246              
247             cycle('Y')/cycle('N') - alter sequence to cycle/not cycle after reaching maxvalue instead of returning an error. Note that cycle('N') and nocycle() are equivalent.
248              
249             =item
250              
251             cycle() - return the current sequence's cycle flag
252              
253             =cut
254              
255             sub cycle {
256             my $self = shift;
257             my $seq = $self->{SEQ};
258             my $cycle_flag = shift;
259              
260             if (defined($cycle_flag)) {
261             $self->{DBH}->do("alter sequence $seq cycle") if $cycle_flag eq 'Y';
262             $self->{DBH}->do("alter sequence $seq nocycle") if $cycle_flag eq 'N';
263             }
264             $self->_getSeqAttribute("CYCLE_FLAG")
265             }
266              
267             =item
268              
269             nocycle() - alter sequence to return an error after reaching maxvalue instead of cycling
270              
271             =cut
272              
273             sub nocycle {
274             my $self = shift;
275             my $seq = $self->{SEQ};
276             $self->{DBH}->do("alter sequence $seq nocycle");
277             $self->_getSeqAttribute("CYCLE_FLAG");
278             }
279              
280             =item
281              
282             order('Y')/order('N') - alter sequence to guarantee/not guarantee that sequence numbers are generated in the order of their request. Note that order('N') and noorder() are equivalent.
283              
284             =item
285              
286             order() - return current sequence's order flag
287              
288             =cut
289              
290             sub order {
291             my $self = shift;
292             my $seq = $self->{SEQ};
293             my $order_flag = shift;
294              
295             if (defined($order_flag)) {
296             $self->{DBH}->do("alter sequence $seq order") if $order_flag eq 'Y';
297             $self->{DBH}->do("alter sequence $seq noorder") if $order_flag eq 'N';
298             }
299             $self->_getSeqAttribute("ORDER_FLAG");
300             }
301              
302             =item
303              
304             noorder() - alter sequence to not guarantee that sequence numbers are generated in order of request
305              
306             =cut
307              
308             sub noorder {
309             my $self = shift;
310             my $seq = $self->{SEQ};
311             $self->{DBH}->do("alter sequence $seq noorder");
312             $self->_getSeqAttribute("ORDER_FLAG");
313             }
314              
315             =item
316              
317             sequenceNameExists() - return 0 if current sequence's name does not already exist as a sequence name, non-zero if it does
318              
319             =item
320              
321             sequenceNameExists($S) - return 0 if $S does not exist as a sequence name, non-zero if it does
322              
323             =cut
324              
325             sub sequenceNameExists {
326             my $self = shift;
327             my $sequenceName = (uc shift) || $self->{SEQ};
328             my $rv = grep(/^$sequenceName$/,@{$self->getSequencesAref});
329             }
330              
331             =item
332              
333             getSequencesAref() - return an arrayRef of all existing sequence names in the current schema
334              
335             =cut
336              
337             sub getSequencesAref {
338             my $self = shift;
339             my $seqArrayRef = $self->{DBH}->selectcol_arrayref("select sequence_name from user_sequences");
340             }
341              
342             =item
343              
344             printSequences() - print all existing sequence names in the current schema
345              
346             =cut
347              
348             sub printSequences {
349             my $self = shift;
350             print join(" ",@{$self->getSequencesAref}), "\n";
351             }
352              
353             =item
354              
355             info() - return a string containing information about the sequence
356              
357             =cut
358              
359             sub info {
360             my $self = shift;
361             my $seq = $self->{SEQ};
362             my $sql = q(select * from user_sequences where SEQUENCE_NAME=?);
363             my $sth = $self->{DBH}->prepare($sql);
364              
365             $sth->execute($seq);
366              
367             my $i=0;
368             my $column;
369             my $rv;
370             foreach $column ($sth->fetchrow_array) {
371             $rv .= $sth->{NAME}->[$i++] . "=$column\n";
372             }
373             $rv;
374             }
375              
376             =item
377              
378             print() - print a string containing information about the sequence
379              
380             =cut
381              
382             sub print {
383             my $self = shift;
384              
385             print "\n", $self->info();
386             }
387              
388             =item
389              
390             drop() - drop the sequence
391              
392             =cut
393              
394             sub drop {
395             my $self = shift;
396             my $seq = $self->{SEQ};
397             $self->{DBH}->do("drop sequence $seq");
398             }
399              
400             }
401             1;
402              
403             =back
404              
405             =head1 COPYRIGHT
406              
407             Copyright (c) 1999 Doug Bloebaum. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
408              
409             =head1 AUTHOR
410              
411             Doug Bloebaum Ebloebaum@dma.orgE